Commit 2a545e24 by junxiang

Initial commit

parents
/node_modules/
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/plan.iml" filepath="$PROJECT_DIR$/.idea/plan.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PrettierConfiguration">
<option name="myConfigurationMode" value="MANUAL" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
{
"name": "plan",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"prettier": "^3.3.3",
"typescript": "^5.6.3"
}
}
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
prettier:
specifier: ^3.3.3
version: 3.3.3
typescript:
specifier: ^5.6.3
version: 5.6.3
packages:
prettier@3.3.3:
resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
engines: {node: '>=14'}
hasBin: true
typescript@5.6.3:
resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
engines: {node: '>=14.17'}
hasBin: true
snapshots:
prettier@3.3.3: {}
typescript@5.6.3: {}
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ES6", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
import { AlignEnums, BoardElementType } from "./enums";
export interface IBoardState {
version: string; //总版本号
id: string;
creatAt: number;
creator: string; //创建者ID
wrapper: {
scale: number; //缩放
};
cover: string; //封面
elements: ICanvasElement[];//自定义节点列表
}
export interface ICanvasElement extends IRectangle {
creator: string; //创作者id
creatAt: number; //创作id
version: string; //版本,用于比对
elType: BoardElementType; //类型
id: string;
zIndex: number; //层级
lock: boolean; //是否锁定
edit: false; //是否在编辑
rotate: boolean; //旋转
fontSize: number;
textAlign: AlignEnums;
verticalAlign: AlignEnums;
paths?: IVec2[]; //轨迹独有的属性
points?: IVec2[]; //线独有的属性
lineType: string; //线独有属性
fillStyle: IStyleLine;
textFillStyle: IStyleLine;
ext: Dictionary<any>;
}
export interface ICanvasElementChangePayload{
}
export enum AlignEnums {
Left='left',
Right='right',
Center='center'
}
export enum BoardElementType {
Note='Note',//笔记
Text='Text',//文本
Image='Image',//图片
Mind='Mind',//思维导图
Ligature='Ligature',//线条
Shape='Shape',//矩形
//more
}
/**
* key-val键值对
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* 元素尺寸
*/
interface IRectangle {
x: number;
y: number;
width: number;
height: number;
}
/**
* RGB颜色
*/
interface IRGBColor {
r: number;
g: number;
b: number;
}
/**
* RGBA颜色
*/
interface IRGBAColor {
r: number;
a: number;
g: number;
b: number;
}
/**
* 平面直角坐标 or 二维向量
*/
interface IVec2 {
x: number;
y: number;
}
/**
* 三维坐标 or 三维向量
*/
interface IVec3 {
x: number;
y: number;
z: number;
}
/**
* 截取区域
*/
interface ICrop {
top: number;
bottom: number;
left: number;
right: number;
}
type IStyleLine = string
# 技术路线概要
# 技术路线概要
## 协作白板
### 主要的功能列表
#### 画布管理
##### 新增
##### 查看
##### 删除
##### 查看
#### 权限管理
##### 开通权限
##### 修改/删除权限
#### 协作
#### 新写作者加入
```
1.前端打开一个文档时,发送请求给服务端,服务端检查协作列表中是否有当前文档。
2.如果有则把当前用户加入此文档修改者列表;如果没有就把当前文档加入协作列表,同时把当前用户ID写入其中。
3.服务端通过长链接给文档列表中的所有其他用户推送消息,告知大家有用户加入协作。
```
#### 数据提交
```
1.前端把修改数据发送给服务端
2.服务端暂存多个用户的操作,并根据OT算法把用户操作合并,最后和数据库存储的文档内容合并
3.把合并完的文档内容保存到数据库中
4.服务端根据文档ID,读取协作列表中的用户,给所有用户发送合并结果
5.客户端把合并结果与本地文档内容合并
```
##### 合并冲突
##### 协作通知
##### 离线暂存
### 数据结构化存储/解析
```
通过json存取
```
### 数据建模
```
参见类型描述文档./types/board.ts
```
### 导出
```
//导出成pdf
canvas2pdf
```
### 进阶
如果对传输文件大小或者性能有更高要求,可以基于Protobuf协议来替换json
## 多人协作编辑器
#### 文稿管理
##### 新增
##### 查看
##### 删除
##### 查看
#### 权限管理
##### 权限分类
管理权限、编辑权限、查看权限、无权限
##### 开通权限
##### 修改/删除权限
#### 协作
#### 新写作者加入
```
1.权限校验,如有权限则拉取文档内容。
2.ws通知其他正在修改同一个文稿的人,有新的协作者加入
```
#### 数据提交
```
1.前端把修改数据发送给服务端
1.1 将变更请求变为阻塞的同步请求
1.2 前端每次请求都生成连续递增的ID,服务端判断如果递增ID不连续了,就短暂的等待
1.3 服务端队列接受,按照连续递增的ID消费。
```
##### 合并冲突
```
1.服务端OT算法合并
2.把合并完的文档内容保存到数据库中,并生成修改记录
3.通过ws给所有的协作者同步最新结果
4.客户端merge云端和本地内容,渲染
```
##### 协作通知
ws
##### 离线暂存
本地通过队列暂存请求失败的数据包,每30S重试一次最小序号的包,如果成功提交则进行下一个
#### 备注
OT算法https://zhuanlan.zhihu.com/p/634121875
## 严肃游戏
## PPT
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment