Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hmisaka committed Nov 14, 2024
0 parents commit 5792c4a
Show file tree
Hide file tree
Showing 182 changed files with 27,740 additions and 0 deletions.
47 changes: 47 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module.exports = {
parserOptions: {
sourceType: "module",
},
extends: ["eslint:recommended", "plugin:prettier/recommended"],
overrides: [
{
files: ["*.ts"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "simple-import-sort"],
extends: ["plugin:@typescript-eslint/recommended"],
},
{
files: ["*.tsx"],
parser: "@typescript-eslint/parser",
plugins: ["react", "react-hooks", "@typescript-eslint/eslint-plugin", "simple-import-sort"],
extends: ["plugin:@typescript-eslint/recommended", "plugin:react-hooks/recommended"],
},
],
env: {
browser: true,
node: true,
commonjs: true,
es2021: true,
},
ignorePatterns: ["node_modules", "build", "dist", "coverage", "public"],
rules: {
// 分号
"semi": "error",
// 对象键值引号样式保持一致
"quote-props": ["error", "consistent-as-needed"],
// 箭头函数允许单参数不带括号
"arrow-parens": ["error", "as-needed"],
// no var
"no-var": "error",
// const
"prefer-const": "error",
// 允许console
"no-console": "off",
// 关闭每个函数都要显式声明返回值
// "@typescript-eslint/explicit-module-boundary-types": "off",
// 偏好import type
"@typescript-eslint/consistent-type-imports": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
},
};
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# log
*.log

# dependencies
node_modules
.pnp
.pnp.js

# testing
coverage

# production
build
dist

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry=https://registry.npmmirror.com/
17 changes: 17 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = {
"printWidth": 100, // 指定代码长度,超出换行
"tabWidth": 2, // tab 键的宽度
"useTabs": false, // 不使用tab
"semi": true, // 结尾加上分号
"singleQuote": false, // 使用单引号
"quoteProps": "preserve", // 不要求对象字面量属性是否使用引号包裹
"jsxSingleQuote": false, // jsx 语法中使用单引号
"trailingComma": "es5", // 确保对象的最后一个属性后有逗号
"bracketSpacing": true, // 大括号有空格 { name: 'rose' }
"arrowParens": "avoid", // 箭头函数,单个参数不强制添加括号
"requirePragma": false, // 是否严格按照文件顶部的特殊注释格式化代码
"insertPragma": false, // 是否在格式化的文件顶部插入Pragma标记,以表明该文件被prettier格式化过了
"proseWrap": "preserve", // 按照文件原样折行
"htmlWhitespaceSensitivity": "ignore", // html文件的空格敏感度,控制空格是否影响布局
"endOfLine": "lf" // 结尾是 \n \r \n\r auto
}
26 changes: 26 additions & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = {
extends: ["stylelint-config-standard", "stylelint-config-sass-guidelines"],
ignoreFiles: [
"**/node_modules/**/*.*",
"**/dist/**/*.*",
"**/build/**/*.*",
"**/coverage/**/*.*",
"**/public/**/*.*",
],
rules: {
"no-descending-specificity": null,
"color-function-notation": null,
"alpha-value-notation": null,
"no-empty-source": null,
"max-nesting-depth": 6,
"selector-max-compound-selectors": 6,
"selector-class-pattern": "^[a-z][a-zA-Z0-9_-]+$",
"selector-id-pattern": "^[a-z][a-zA-Z0-9_-]+$",
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["global"],
},
],
},
};
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Czy

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
54 changes: 54 additions & 0 deletions NOTE.md

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# CanvasEditor

<p>
<a href="https://github.com/WindrunnerMax/CanvasEditor">GitHub</a>
<span>|</span>
<a href="https://windrunnermax.github.io/CanvasEditor/">DEMO</a>
<span>|</span>
<a href="https://github.com/WindrunnerMax/CanvasEditor/issues/2">BLOG</a>
<span>|</span>
<a href="./NOTE.md">NOTE</a>
<span>|</span>
<a href="./TODO.md">TODO</a>
</p>

基于`Canvas`实现的的简历编辑器。


```bash
$ npm i -g pnpm
$ pnpm install
$ npm run dev:react
```

## FAQ

为什么要自行实现一个简历编辑器:

1. 固定模版不好用,各种模版用起来细节上并不是很满意,要么是模块的位置固定,要么是页面边距不满意,而通过`Canvas`实现的简历编辑器都是图形,完全依靠画布绘制图形,在给定的基础图形上可以任意绘制,不会有排版问题。
2. 数据安全不能保证,因为简历上通常会存在很多个人信息,例如电话、邮箱等等,这些简历网站通常都需要登录才能用,数据都存在服务端,虽然泄漏的可能性不大,但是保护隐私还是很重要的,此编辑器是纯前端项目,数据全部存储在本地,没有任何服务器上传行为,可以完全保证数据安全。
3. 维持一页简历不易,之前使用某简历模版网站时,某一项写的字较多时导出就会出现多页的情况,而我们大家大概都听说过简历最好是一页,所以在实现此编辑器时是直接通过排版的方式生成`PDF` ,所以在设置页面大小后,导出的`PDF`总会是保持一页,看起来会更美观。

22 changes: 22 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# TODO
- [x] 数据结构
- [x] 事件管理
- [x] 原子操作
- [x] 画布分层
- [x] 区域绘制
- [x] 无限画布
- [x] 插件化
- [x] 选区模块
- [x] 基础图形
- [x] 参考线
- [x] 富文本
- [x] 配置面板
- [x] 快捷键
- [x] 后退前进
- [x] 层级调整
- [x] 页面配置
- [x] 导入导出`JSON`
- [x] 超链接导出
- [x] 排版`PDF`导出
- [x] 复制粘贴模块
- [ ] 直线图形
40 changes: 40 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "cv-sketching",
"version": "1.0.0",
"scripts": {
"dev": "pnpm --filter sketching-react run dev",
"dev:react": "pnpm --filter sketching-react run dev",
"build:react": "pnpm --filter sketching-react run build",
"build:workspace": "pnpm --filter '*' run build",
"lint:ts": "pnpm --filter '*' run lint:ts"
},
"repository": {
"type": "git",
"url": "git+https://github.com/WindrunnerMax/CVEditor.git"
},
"keywords": [],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/WindrunnerMax/CVEditor/issues"
},
"homepage": "https://github.com/WindrunnerMax/CVEditor",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "6.12.0",
"@typescript-eslint/parser": "6.12.0",
"eslint": "7.11.0",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-import": "2.25.3",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-react": "7.27.0",
"eslint-plugin-react-hooks": "4.3.0",
"eslint-plugin-simple-import-sort": "^10.0.0",
"postcss": "8.3.3",
"prettier": "2.4.1",
"sass": "1.52.3",
"stylelint": "14.7.1",
"stylelint-config-sass-guidelines": "9.0.1",
"stylelint-config-standard": "25.0.0",
"typescript": "5.3.2"
}
}
3 changes: 3 additions & 0 deletions packages/core/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"],
};
14 changes: 14 additions & 0 deletions packages/core/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
moduleFileExtensions: ["js", "ts"],
moduleDirectories: ["node_modules", "src", "test"],
moduleNameMapper: {
"src/(.*)$": "<rootDir>/src/$1",
},
transform: {
"\\.ts$": "ts-jest",
"\\.js$": "babel-jest",
},
transformIgnorePatterns: ["<rootDir>/node_modules/"],
collectCoverage: false,
testMatch: ["<rootDir>/test/**/*.test.ts"],
};
34 changes: 34 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "sketching-core",
"version": "0.0.1",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"files": [
"dist"
],
"scripts": {
"build": "tsc -p tsconfig.build.json",
"release": "./publish.sh",
"test": "jest",
"lint:ts": "../../node_modules/typescript/bin/tsc --noEmit"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"resize-observer-polyfill": "1.5.1",
"sketching-delta": "workspace: *",
"sketching-utils": "workspace: *"
},
"devDependencies": {
"@babel/core": "7.20.12",
"@babel/preset-env": "7.20.2",
"@babel/preset-typescript": "7.18.6",
"@types/jest": "29.4.0",
"babel-jest": "29.4.1",
"jest": "29.4.1",
"ts-jest": "29.0.5"
}
}
3 changes: 3 additions & 0 deletions packages/core/publish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
npm version patch --no-git-tag-version
npm run build
npm publish --registry=https://registry.npmjs.org/
76 changes: 76 additions & 0 deletions packages/core/src/canvas/dom/element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { BLUE_4 } from "sketching-utils";

import type { Editor } from "../../editor";
import type { DeltaState } from "../../state/modules/node";
import { EDITOR_STATE } from "../../state/utils/constant";
import type { MouseEvent } from "../event/mouse";
import { Shape } from "../utils/shape";
import { Node } from "./node";

export class ElementNode extends Node {
/** 节点 id */
public readonly id: string;
/** Hover 状态 */
private isHovering: boolean;

constructor(private editor: Editor, state: DeltaState) {
const range = state.toRange();
super(range);
this.id = state.id;
const delta = state.toDelta();
const rect = delta.getRect();
this.setZ(rect.z);
this.isHovering = false;
}

protected onMouseDown = (e: MouseEvent) => {
if (e.shiftKey) {
this.editor.selection.addActiveDelta(this.id);
} else {
this.editor.selection.setActiveDelta(this.id);
}
};

/**
* 触发节点的 Hover 效果
* @description Root - MouseLeave
*/
protected onMouseEnter = () => {
this.isHovering = true;
if (this.editor.selection.has(this.id)) {
return void 0;
}
this.editor.canvas.mask.drawingEffect(this.range);
};

/**
* 移除节点的 Hover 效果
* @description Root - MouseLeave
*/
protected onMouseLeave = () => {
this.isHovering = false;
if (this.editor.selection.has(this.id)) {
return void 0;
}
this.editor.canvas.mask.drawingEffect(this.range);
};

public drawingMask = (ctx: CanvasRenderingContext2D) => {
if (
this.isHovering &&
// FIX: 避免全选删除后的 Hover 绘制
this.editor.deltaSet.has(this.id) &&
!this.editor.selection.has(this.id) &&
!this.editor.state.get(EDITOR_STATE.MOUSE_DOWN)
) {
const { x, y, width, height } = this.range.rect();
Shape.frame(ctx, {
x: x,
y: y,
width: width,
height: height,
borderColor: BLUE_4,
});
}
};
}
Loading

0 comments on commit 5792c4a

Please sign in to comment.