cbvirtua 1.0.41 → 1.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/canvas-event-system/.babelrc +17 -0
  2. package/canvas-event-system/.prettierrc +9 -0
  3. package/canvas-event-system/package-lock.json +6825 -0
  4. package/canvas-event-system/package.json +40 -0
  5. package/canvas-event-system/readme.md +13 -0
  6. package/canvas-event-system/src/canvas-event-system/EventSimulator.ts +75 -0
  7. package/canvas-event-system/src/canvas-event-system/helpers.ts +27 -0
  8. package/canvas-event-system/src/canvas-event-system/index.ts +64 -0
  9. package/canvas-event-system/src/canvas-event-system/shapes/Base.ts +32 -0
  10. package/canvas-event-system/src/canvas-event-system/shapes/Circle.ts +46 -0
  11. package/canvas-event-system/src/canvas-event-system/shapes/Path.ts +0 -0
  12. package/canvas-event-system/src/canvas-event-system/shapes/Rect.ts +46 -0
  13. package/canvas-event-system/src/canvas-event-system/shapes/index.ts +5 -0
  14. package/canvas-event-system/src/canvas-event-system/shapes/types.ts +22 -0
  15. package/canvas-event-system/src/index.html +12 -0
  16. package/canvas-event-system/src/index.ts +30 -0
  17. package/canvas-event-system/tsconfig.json +17 -0
  18. package/canvas-event-system/webpack.config.js +28 -0
  19. package/hanzi-writer/.prettierrc.json +7 -0
  20. package/hanzi-writer/COPYING.md +11 -0
  21. package/hanzi-writer/LICENSE +20 -0
  22. package/hanzi-writer/README.md +37 -0
  23. package/hanzi-writer/babel.config.js +14 -0
  24. package/hanzi-writer/dist/types/HanziWriter.d.ts +108 -0
  25. package/hanzi-writer/dist/types/LoadingManager.d.ts +20 -0
  26. package/hanzi-writer/dist/types/Positioner.d.ts +22 -0
  27. package/hanzi-writer/dist/types/Quiz.d.ts +40 -0
  28. package/hanzi-writer/dist/types/RenderState.d.ts +74 -0
  29. package/hanzi-writer/dist/types/__tests__/HanziWriter-test.d.ts +1 -0
  30. package/hanzi-writer/dist/types/__tests__/LoadingManager-test.d.ts +1 -0
  31. package/hanzi-writer/dist/types/__tests__/Mutation-test.d.ts +1 -0
  32. package/hanzi-writer/dist/types/__tests__/Positioner-test.d.ts +1 -0
  33. package/hanzi-writer/dist/types/__tests__/Quiz-test.d.ts +1 -0
  34. package/hanzi-writer/dist/types/__tests__/RenderState-test.d.ts +1 -0
  35. package/hanzi-writer/dist/types/__tests__/defaultCharDataLoader-test.d.ts +1 -0
  36. package/hanzi-writer/dist/types/__tests__/geometry-test.d.ts +1 -0
  37. package/hanzi-writer/dist/types/__tests__/parseCharData-test.d.ts +1 -0
  38. package/hanzi-writer/dist/types/__tests__/strokeMatches-test.d.ts +1 -0
  39. package/hanzi-writer/dist/types/__tests__/utils-test.d.ts +1 -0
  40. package/hanzi-writer/dist/types/characterActions.d.ts +18 -0
  41. package/hanzi-writer/dist/types/defaultCharDataLoader.d.ts +3 -0
  42. package/hanzi-writer/dist/types/defaultOptions.d.ts +3 -0
  43. package/hanzi-writer/dist/types/geometry.d.ts +38 -0
  44. package/hanzi-writer/dist/types/models/Character.d.ts +6 -0
  45. package/hanzi-writer/dist/types/models/Stroke.d.ts +17 -0
  46. package/hanzi-writer/dist/types/models/UserStroke.d.ts +8 -0
  47. package/hanzi-writer/dist/types/parseCharData.d.ts +3 -0
  48. package/hanzi-writer/dist/types/quizActions.d.ts +10 -0
  49. package/hanzi-writer/dist/types/renderers/HanziWriterRendererBase.d.ts +14 -0
  50. package/hanzi-writer/dist/types/renderers/RenderTargetBase.d.ts +22 -0
  51. package/hanzi-writer/dist/types/renderers/StrokeRendererBase.d.ts +13 -0
  52. package/hanzi-writer/dist/types/renderers/canvas/CharacterRenderer.d.ts +14 -0
  53. package/hanzi-writer/dist/types/renderers/canvas/HanziWriterRenderer.d.ts +19 -0
  54. package/hanzi-writer/dist/types/renderers/canvas/RenderTarget.d.ts +6 -0
  55. package/hanzi-writer/dist/types/renderers/canvas/StrokeRenderer.d.ts +16 -0
  56. package/hanzi-writer/dist/types/renderers/canvas/__tests__/CharacterRenderer-test.d.ts +1 -0
  57. package/hanzi-writer/dist/types/renderers/canvas/__tests__/HanziWriterRenderer-test.d.ts +1 -0
  58. package/hanzi-writer/dist/types/renderers/canvas/__tests__/RenderTarget-test.d.ts +1 -0
  59. package/hanzi-writer/dist/types/renderers/canvas/__tests__/StrokeRenderer-test.d.ts +1 -0
  60. package/hanzi-writer/dist/types/renderers/canvas/__tests__/canvasUtils-test.d.ts +1 -0
  61. package/hanzi-writer/dist/types/renderers/canvas/__tests__/renderUserStroke-test.d.ts +1 -0
  62. package/hanzi-writer/dist/types/renderers/canvas/canvasUtils.d.ts +9 -0
  63. package/hanzi-writer/dist/types/renderers/canvas/index.d.ts +7 -0
  64. package/hanzi-writer/dist/types/renderers/canvas/renderUserStroke.d.ts +7 -0
  65. package/hanzi-writer/dist/types/renderers/svg/CharacterRenderer.d.ts +20 -0
  66. package/hanzi-writer/dist/types/renderers/svg/HanziWriterRenderer.d.ts +20 -0
  67. package/hanzi-writer/dist/types/renderers/svg/RenderTarget.d.ts +11 -0
  68. package/hanzi-writer/dist/types/renderers/svg/StrokeRenderer.d.ts +21 -0
  69. package/hanzi-writer/dist/types/renderers/svg/UserStrokeRenderer.d.ts +15 -0
  70. package/hanzi-writer/dist/types/renderers/svg/__tests__/CharacterRenderer-test.d.ts +1 -0
  71. package/hanzi-writer/dist/types/renderers/svg/__tests__/HanziWriterRenderer-test.d.ts +1 -0
  72. package/hanzi-writer/dist/types/renderers/svg/__tests__/StrokeRenderer-test.d.ts +1 -0
  73. package/hanzi-writer/dist/types/renderers/svg/__tests__/svgUtils-test.d.ts +1 -0
  74. package/hanzi-writer/dist/types/renderers/svg/index.d.ts +7 -0
  75. package/hanzi-writer/dist/types/renderers/svg/svgUtils.d.ts +5 -0
  76. package/hanzi-writer/dist/types/strokeMatches.d.ts +14 -0
  77. package/hanzi-writer/dist/types/testUtils.d.ts +1 -0
  78. package/hanzi-writer/dist/types/typings/types.d.ts +121 -0
  79. package/hanzi-writer/dist/types/utils.d.ts +26 -0
  80. package/hanzi-writer/jest-jsdom-env.js +20 -0
  81. package/hanzi-writer/package.json +66 -0
  82. package/hanzi-writer/rollup.config.js +58 -0
  83. package/hanzi-writer/tsconfig.json +79 -0
  84. package/package.json +1 -1
  85. package/pdf.js-2.9.359.zip +0 -0
  86. package/pdfjs-dist-2.15.349.zip +0 -0
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "canvas-event-system",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "start": "webpack-dev-server"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/JS-Hao/canvas-event-system.git"
12
+ },
13
+ "keywords": [
14
+ "canvas",
15
+ "event",
16
+ "system",
17
+ "listeners"
18
+ ],
19
+ "author": "JS-Hao",
20
+ "license": "ISC",
21
+ "bugs": {
22
+ "url": "https://github.com/JS-Hao/canvas-event-system/issues"
23
+ },
24
+ "homepage": "https://github.com/JS-Hao/canvas-event-system#readme",
25
+ "devDependencies": {
26
+ "@babel/core": "^7.12.3",
27
+ "@babel/plugin-proposal-class-properties": "^7.12.1",
28
+ "@babel/plugin-transform-runtime": "^7.12.1",
29
+ "@babel/preset-env": "^7.12.1",
30
+ "@babel/preset-typescript": "^7.12.1",
31
+ "babel-loader": "^8.1.0",
32
+ "typescript": "^4.0.3",
33
+ "webpack": "^4.44.2",
34
+ "webpack-cli": "^3.3.2",
35
+ "webpack-dev-server": "^3.3.1"
36
+ },
37
+ "dependencies": {
38
+ "uuid": "^8.3.1"
39
+ }
40
+ }
@@ -0,0 +1,13 @@
1
+ ## 一个简易的 Canvas 事件系统
2
+
3
+ ### 食用方法
4
+
5
+ 执行如下命令行:
6
+
7
+ ```
8
+ npm start
9
+ ```
10
+
11
+ 访问`http://localhost:9000`即可
12
+
13
+ ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a54e80ebb2184f0fa5fddbde16b60bd3~tplv-k3u1fbpfcp-watermark.image)
@@ -0,0 +1,75 @@
1
+ import { Listener, EventNames } from './shapes';
2
+
3
+ export interface Action {
4
+ type: ActionType;
5
+ id: string;
6
+ }
7
+
8
+ export enum ActionType {
9
+ Down = 'DOWN',
10
+ Up = 'Up',
11
+ Move = 'MOVE',
12
+ }
13
+
14
+ export default class EventSimulator {
15
+ private listenersMap: {
16
+ [id: string]: {
17
+ [eventName: string]: Listener[];
18
+ };
19
+ } = {};
20
+
21
+ private lastDownId: string;
22
+ private lastMoveId: string;
23
+
24
+ addAction(action: Action, evt: MouseEvent) {
25
+ const { type, id } = action;
26
+
27
+ // mousemove
28
+ if (type === ActionType.Move) {
29
+ this.fire(id, EventNames.mousemove, evt);
30
+ }
31
+
32
+ // mouseover
33
+ // mouseenter
34
+ if (type === ActionType.Move && (!this.lastMoveId || this.lastMoveId !== id)) {
35
+ this.fire(id, EventNames.mouseenter, evt);
36
+ this.fire(this.lastMoveId, EventNames.mouseleave, evt);
37
+ }
38
+
39
+ // mousedown
40
+ if (type === ActionType.Down) {
41
+ this.fire(id, EventNames.mousedown, evt);
42
+ }
43
+
44
+ // mouseup
45
+ if (type === ActionType.Up) {
46
+ this.fire(id, EventNames.mouseup, evt);
47
+ }
48
+
49
+ // click
50
+ if (type === ActionType.Up && this.lastDownId === id) {
51
+ this.fire(id, EventNames.click, evt);
52
+ }
53
+
54
+ if (type === ActionType.Move) {
55
+ this.lastMoveId = action.id;
56
+ } else if (type === ActionType.Down) {
57
+ this.lastDownId = action.id;
58
+ }
59
+ }
60
+
61
+ addListeners(
62
+ id: string,
63
+ listeners: {
64
+ [eventName: string]: Listener[];
65
+ },
66
+ ) {
67
+ this.listenersMap[id] = listeners;
68
+ }
69
+
70
+ fire(id: string, eventName: EventNames, evt: MouseEvent) {
71
+ if (this.listenersMap[id] && this.listenersMap[id][eventName]) {
72
+ this.listenersMap[id][eventName].forEach((listener) => listener(evt));
73
+ }
74
+ }
75
+ }
@@ -0,0 +1,27 @@
1
+ export function idToRgba(id: string) {
2
+ return id.split("-");
3
+ }
4
+
5
+ export function rgbaToId(rgba: [number, number, number, number]) {
6
+ return rgba.join("-");
7
+ }
8
+
9
+ const idPool = {};
10
+
11
+ export function createId(): string {
12
+ let id = createOnceId();
13
+
14
+ while (idPool[id]) {
15
+ id = createOnceId();
16
+ }
17
+
18
+ return id;
19
+ }
20
+
21
+ function createOnceId(): string {
22
+ return Array(3)
23
+ .fill(0)
24
+ .map(() => Math.ceil(Math.random() * 255))
25
+ .concat(255)
26
+ .join("-");
27
+ }
@@ -0,0 +1,64 @@
1
+ import { rgbaToId } from './helpers';
2
+ import { Shape } from './shapes/types';
3
+ import EventSimulator, { ActionType } from './EventSimulator';
4
+ export * from './shapes';
5
+
6
+ export class Stage {
7
+ private canvas: HTMLCanvasElement;
8
+ private osCanvas: OffscreenCanvas;
9
+ private ctx: CanvasRenderingContext2D;
10
+ private osCtx: OffscreenCanvasRenderingContext2D;
11
+ private dpr: number;
12
+ private shapes: Set<string>;
13
+ private eventSimulator: EventSimulator;
14
+
15
+ constructor(canvas: HTMLCanvasElement) {
16
+ const dpr = window.devicePixelRatio;
17
+ canvas.width = parseInt(canvas.style.width) * dpr;
18
+ canvas.height = parseInt(canvas.style.height) * dpr;
19
+
20
+ this.canvas = canvas;
21
+ this.osCanvas = new OffscreenCanvas(canvas.width, canvas.height);
22
+
23
+ this.ctx = this.canvas.getContext('2d');
24
+ this.osCtx = this.osCanvas.getContext('2d');
25
+
26
+ this.ctx.scale(dpr, dpr);
27
+ this.osCtx.scale(dpr, dpr);
28
+ this.dpr = dpr;
29
+
30
+ this.canvas.addEventListener('mousedown', this.handleCreator(ActionType.Down));
31
+ this.canvas.addEventListener('mouseup', this.handleCreator(ActionType.Up));
32
+ this.canvas.addEventListener('mousemove', this.handleCreator(ActionType.Move));
33
+
34
+ this.shapes = new Set();
35
+ this.eventSimulator = new EventSimulator();
36
+ }
37
+
38
+ add(shape: Shape) {
39
+ const id = shape.getId();
40
+ this.eventSimulator.addListeners(id, shape.getListeners());
41
+ this.shapes.add(id);
42
+
43
+ shape.draw(this.ctx, this.osCtx);
44
+ }
45
+
46
+ private handleCreator = (type: ActionType) => (evt: MouseEvent) => {
47
+ const x = evt.offsetX;
48
+ const y = evt.offsetY;
49
+ const id = this.hitJudge(x, y);
50
+ this.eventSimulator.addAction({ type, id }, evt);
51
+ };
52
+
53
+ /**
54
+ * Determine whether the current position is inside a certain shape, if it is, then return its id
55
+ * @param x
56
+ * @param y
57
+ */
58
+ private hitJudge(x: number, y: number): string {
59
+ const rgba = Array.from(this.osCtx.getImageData(x * this.dpr, y * this.dpr, 1, 1).data);
60
+
61
+ const id = rgbaToId(rgba as [number, number, number, number]);
62
+ return this.shapes.has(id) ? id : undefined;
63
+ }
64
+ }
@@ -0,0 +1,32 @@
1
+ import { EventNames, Listener, Shape } from './types';
2
+ import { createId } from '../helpers';
3
+
4
+ export default class Base implements Shape {
5
+ private listeners: { [eventName: string]: Listener[] };
6
+ public id: string;
7
+
8
+ constructor() {
9
+ this.id = createId();
10
+ this.listeners = {};
11
+ }
12
+
13
+ draw(ctx: CanvasRenderingContext2D, osCtx: OffscreenCanvasRenderingContext2D): void {
14
+ throw new Error('Method not implemented.');
15
+ }
16
+
17
+ on(eventName: EventNames, listener: Listener): void {
18
+ if (this.listeners[eventName]) {
19
+ this.listeners[eventName].push(listener);
20
+ } else {
21
+ this.listeners[eventName] = [listener];
22
+ }
23
+ }
24
+
25
+ getListeners(): { [name: string]: Listener[] } {
26
+ return this.listeners;
27
+ }
28
+
29
+ getId(): string {
30
+ return this.id;
31
+ }
32
+ }
@@ -0,0 +1,46 @@
1
+ import { idToRgba } from '../helpers';
2
+ import Base from './Base';
3
+
4
+ interface RectProps {
5
+ x: number;
6
+ y: number;
7
+ radius: number;
8
+ strokeWidth?: number;
9
+ strokeColor?: string;
10
+ fillColor?: string;
11
+ }
12
+
13
+ export default class Circle extends Base {
14
+ constructor(private props: RectProps) {
15
+ super();
16
+ this.props.fillColor = this.props.fillColor || '#fff';
17
+ this.props.strokeColor = this.props.strokeColor || '#000';
18
+ this.props.strokeWidth = this.props.strokeWidth || 1;
19
+ }
20
+
21
+ draw(ctx: CanvasRenderingContext2D, osCtx: OffscreenCanvasRenderingContext2D) {
22
+ const { x, y, radius, strokeColor, strokeWidth, fillColor } = this.props;
23
+
24
+ ctx.save();
25
+ ctx.beginPath();
26
+ ctx.fillStyle = fillColor;
27
+ ctx.strokeStyle = strokeColor;
28
+ ctx.lineWidth = strokeWidth;
29
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
30
+ ctx.fill();
31
+ ctx.stroke();
32
+ ctx.restore();
33
+
34
+ const [r, g, b, a] = idToRgba(this.id);
35
+
36
+ osCtx.save();
37
+ osCtx.beginPath();
38
+ osCtx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
39
+ osCtx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
40
+ osCtx.lineWidth = strokeWidth;
41
+ osCtx.arc(x, y, radius, 0, Math.PI * 2);
42
+ osCtx.fill();
43
+ osCtx.stroke();
44
+ osCtx.restore();
45
+ }
46
+ }
@@ -0,0 +1,46 @@
1
+ import { idToRgba } from '../helpers';
2
+ import Base from './Base';
3
+
4
+ interface RectProps {
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ strokeWidth?: number;
10
+ strokeColor?: string;
11
+ fillColor?: string;
12
+ }
13
+
14
+ export default class Rect extends Base {
15
+ constructor(private props: RectProps) {
16
+ super();
17
+ this.props.fillColor = this.props.fillColor || '#fff';
18
+ this.props.strokeColor = this.props.strokeColor || '#000';
19
+ this.props.strokeWidth = this.props.strokeWidth || 1;
20
+ }
21
+
22
+ draw(ctx: CanvasRenderingContext2D, osCtx: OffscreenCanvasRenderingContext2D) {
23
+ const { x, y, width, height, strokeColor, strokeWidth, fillColor } = this.props;
24
+
25
+ ctx.save();
26
+ ctx.beginPath();
27
+ ctx.strokeStyle = strokeColor;
28
+ ctx.lineWidth = strokeWidth;
29
+ ctx.fillStyle = fillColor;
30
+ ctx.rect(x, y, width, height);
31
+ ctx.fill();
32
+ ctx.stroke();
33
+ ctx.restore();
34
+
35
+ const [r, g, b, a] = idToRgba(this.id);
36
+
37
+ osCtx.save();
38
+ osCtx.beginPath();
39
+ osCtx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
40
+ osCtx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
41
+ osCtx.rect(x, y, width, height);
42
+ osCtx.fill();
43
+ osCtx.stroke();
44
+ osCtx.restore();
45
+ }
46
+ }
@@ -0,0 +1,5 @@
1
+ import Rect from './Rect';
2
+ import Circle from './Circle';
3
+
4
+ export * from './types';
5
+ export { Rect, Circle };
@@ -0,0 +1,22 @@
1
+ export interface Shape {
2
+ draw(ctx: CanvasRenderingContext2D, osCtx: OffscreenCanvasRenderingContext2D): void;
3
+
4
+ on(name: string, listener: Listener): void;
5
+
6
+ getListeners(): { [name: string]: Listener[] };
7
+
8
+ getId(): string;
9
+ }
10
+
11
+ export interface Listener {
12
+ (evt: MouseEvent): void;
13
+ }
14
+
15
+ export enum EventNames {
16
+ click = 'click',
17
+ mousedown = 'mousedown',
18
+ mousemove = 'mousemove',
19
+ mouseup = 'mouseup',
20
+ mouseenter = 'mouseenter',
21
+ mouseleave = 'mouseleave',
22
+ }
@@ -0,0 +1,12 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8" />
4
+ <title>canvas-event-system</title>
5
+ </head>
6
+ <body>
7
+ <canvas id="canvas" style="width: 500px; height: 350px; border: 1px solid #000;"></canvas>
8
+
9
+ <script src="./index.js"></script>
10
+ <script></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,30 @@
1
+ import { Stage, Rect, Circle, EventNames } from './canvas-event-system';
2
+
3
+ const canvas = document.querySelector('#canvas') as HTMLCanvasElement;
4
+ const stage = new Stage(canvas);
5
+
6
+ const rect = new Rect({
7
+ x: 50,
8
+ y: 50,
9
+ width: 250,
10
+ height: 175,
11
+ fillColor: 'green',
12
+ });
13
+
14
+ const circle = new Circle({
15
+ x: 200,
16
+ y: 200,
17
+ radius: 100,
18
+ fillColor: 'red',
19
+ });
20
+
21
+ rect.on(EventNames.mousedown, () => console.log('rect mousedown'));
22
+ rect.on(EventNames.mouseup, () => console.log('rect mouseup'));
23
+ rect.on(EventNames.mouseenter, () => console.log('rect mouseenter'));
24
+ rect.on(EventNames.click, () => console.log('rect click'));
25
+
26
+ circle.on(EventNames.click, () => console.log('circle click!!'));
27
+ circle.on(EventNames.mouseleave, () => console.log('circle mouseleave!'));
28
+
29
+ stage.add(rect);
30
+ stage.add(circle);
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "module": "ESNext",
5
+ "jsx": "react",
6
+ "jsxFactory": "h",
7
+ "importHelpers": true,
8
+ "moduleResolution": "node",
9
+ "declaration": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ //json
12
+ "resolveJsonModule": true,
13
+ "esModuleInterop": true,
14
+ "baseUrl": ".",
15
+ "outDir": "./build"
16
+ }
17
+ }
@@ -0,0 +1,28 @@
1
+ const path = require("path");
2
+
3
+ module.exports = {
4
+ entry: {
5
+ index: "./src/index.ts",
6
+ },
7
+ output: {
8
+ filename: "[name].js",
9
+ path: path.resolve(__dirname, "dist"),
10
+ },
11
+ module: {
12
+ rules: [
13
+ {
14
+ test: /\.(ts|tsx)$/,
15
+ use: "babel-loader",
16
+ },
17
+ ],
18
+ },
19
+ devServer: {
20
+ contentBase: path.join(__dirname, "src"),
21
+ compress: true,
22
+ port: 9000,
23
+ host: "0.0.0.0",
24
+ },
25
+ resolve: {
26
+ extensions: [".ts", ".tsx", ".js", ".jsx"],
27
+ },
28
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "trailingComma": "all",
3
+ "tabWidth": 2,
4
+ "semi": true,
5
+ "singleQuote": true,
6
+ "printWidth": 90
7
+ }
@@ -0,0 +1,11 @@
1
+ Hanzi Writer uses data from the excellent [Make Me a Hanzi](https://github.com/skishore/makemeahanzi) project and fonts from [Arphic](http://www.arphic.com.tw/en/home/index). You can redistribute and/or modify the font data under the terms of the Arphic Public License as published by Arphic Technology Co., Ltd. You should have
2
+ received a copy of this license (the directory "APL") in the data folder of this repository;
3
+ if not, see <http://ftp.gnu.org/non-gnu/chinese-fonts-truetype/LICENSE>.
4
+
5
+ Arphic PL KaitiM GB and UKai
6
+ Copyright 1999 Arphic Technology Co., Ltd.; licensed under the Arphic Public License
7
+ http://www.arphic.com.tw/en/home/index
8
+
9
+ Make Me a Hanzi
10
+ Copyright 1999 Arphic Technology Co., Ltd., copyright 2016 Shaunak Kishore; licensed under the Arphic Public License
11
+ https://github.com/skishore/makemeahanzi
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 David Chanin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,37 @@
1
+
2
+ Hanzi Writer
3
+ =====================
4
+
5
+ [![CircleCI](https://img.shields.io/circleci/project/github/chanind/hanzi-writer/master.svg)](https://circleci.com/gh/chanind/hanzi-writer/tree/master)
6
+ [![Codecov](https://img.shields.io/codecov/c/github/chanind/hanzi-writer/master.svg)](https://codecov.io/gh/chanind/hanzi-writer)
7
+ [![npm](https://img.shields.io/npm/v/hanzi-writer.svg)](https://www.npmjs.com/package/hanzi-writer)
8
+
9
+ https://chanind.github.io/hanzi-writer
10
+
11
+ Hanzi Writer is a free and open-source javascript library for Chinese character stroke order animations and stroke order practice quizzes. Works with both simplified and traditional characters.
12
+
13
+ [Live demo](https://chanind.github.io/hanzi-writer/demo.html)
14
+
15
+ ## Getting Started and Documentation
16
+
17
+ For more info and instructions on getting started check out https://chanind.github.io/hanzi-writer
18
+
19
+ ## Data source
20
+
21
+ The chinese character svg and stroke order data used by Hanzi Writer is derived from the [Make me a Hanzi](https://github.com/skishore/makemeahanzi) project with some slight tweaks. The data can be found in the [Hanzi Writer Data](https://github.com/chanind/hanzi-writer-data) repo. There's a visualizer for this data [here](https://chanind.github.io/hanzi-writer-data).
22
+
23
+ ## Contributing
24
+
25
+ Pull requests are welcome! If you would like to contribute code, you'll need to be able to build the project locally. After cloning the Hanzi Writer repo, you can get it set up by running:
26
+
27
+ ```
28
+ yarn install
29
+ ```
30
+
31
+ You can run tests with `yarn test` and you can build the project with `yarn build`.
32
+
33
+ ## License
34
+
35
+ Hanzi Writer is released under an [MIT](https://raw.githubusercontent.com/chanind/hanzi-writer/master/LICENSE) license.
36
+
37
+ The Hanzi Writer data comes from the [Make Me A Hanzi](https://github.com/skishore/makemeahanzi) project, which extracted the data from fonts by [Arphic Technology](http://www.arphic.com/), a Taiwanese font forge that released their work under a permissive license in 1999. You can redistribute and/or modify this data under the terms of the Arphic Public License as published by Arphic Technology Co., Ltd. A copy of this license can be found in [ARPHICPL.TXT](https://raw.githubusercontent.com/chanind/hanzi-writer-data/master/ARPHICPL.TXT).
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ presets: [
3
+ [
4
+ '@babel/preset-env',
5
+ {
6
+ targets: {
7
+ browsers: '>2%',
8
+ node: '12',
9
+ },
10
+ },
11
+ ],
12
+ '@babel/preset-typescript',
13
+ ],
14
+ };
@@ -0,0 +1,108 @@
1
+ import RenderState from './RenderState';
2
+ import Positioner from './Positioner';
3
+ import Quiz from './Quiz';
4
+ import LoadingManager from './LoadingManager';
5
+ import Character from './models/Character';
6
+ import HanziWriterRendererBase, { HanziWriterRendererConstructor } from './renderers/HanziWriterRendererBase';
7
+ import RenderTargetBase from './renderers/RenderTargetBase';
8
+ import { ColorOptions, DimensionOptions, HanziWriterOptions, LoadingManagerOptions, OnCompleteFunction, ParsedHanziWriterOptions, QuizOptions, RenderTargetInitFunction } from './typings/types';
9
+ export * from './typings/types';
10
+ export default class HanziWriter {
11
+ _options: ParsedHanziWriterOptions;
12
+ _loadingManager: LoadingManager;
13
+ /** Only set when calling .setCharacter() */
14
+ _char: string | undefined;
15
+ /** Only set when calling .setCharacter() */
16
+ _renderState: RenderState | undefined;
17
+ /** Only set when calling .setCharacter() */
18
+ _character: Character | undefined;
19
+ /** Only set when calling .setCharacter() */
20
+ _positioner: Positioner | undefined;
21
+ /** Only set when calling .setCharacter() */
22
+ _hanziWriterRenderer: HanziWriterRendererBase<HTMLElement, any> | null | undefined;
23
+ /** Only set when calling .setCharacter() */
24
+ _withDataPromise: Promise<void> | undefined;
25
+ _quiz: Quiz | undefined;
26
+ _renderer: {
27
+ HanziWriterRenderer: HanziWriterRendererConstructor;
28
+ createRenderTarget: RenderTargetInitFunction<any>;
29
+ };
30
+ target: RenderTargetBase;
31
+ /** Main entry point */
32
+ static create(element: string | HTMLElement, character: string, options?: Partial<HanziWriterOptions>): HanziWriter;
33
+ /** Singleton instance of LoadingManager. Only set in `loadCharacterData` */
34
+ static _loadingManager: LoadingManager | null;
35
+ /** Singleton loading options. Only set in `loadCharacterData` */
36
+ static _loadingOptions: Partial<HanziWriterOptions> | null;
37
+ static loadCharacterData(character: string, options?: Partial<LoadingManagerOptions>): Promise<void | import("./typings/types").CharacterJson>;
38
+ static getScalingTransform(width: number, height: number, padding?: number): {
39
+ x: number;
40
+ y: number;
41
+ scale: number;
42
+ transform: string;
43
+ };
44
+ constructor(element: string | HTMLElement, options?: Partial<HanziWriterOptions>);
45
+ showCharacter(options?: {
46
+ onComplete?: OnCompleteFunction;
47
+ duration?: number;
48
+ }): Promise<Promise<{
49
+ canceled: boolean;
50
+ }> | undefined>;
51
+ hideCharacter(options?: {
52
+ onComplete?: OnCompleteFunction;
53
+ duration?: number;
54
+ }): Promise<Promise<{
55
+ canceled: boolean;
56
+ }> | undefined>;
57
+ animateCharacter(options?: {
58
+ onComplete?: OnCompleteFunction;
59
+ }): Promise<Promise<{
60
+ canceled: boolean;
61
+ }> | undefined>;
62
+ animateStroke(strokeNum: number, options?: {
63
+ onComplete?: OnCompleteFunction;
64
+ }): Promise<Promise<{
65
+ canceled: boolean;
66
+ }> | undefined>;
67
+ highlightStroke(strokeNum: number, options?: {
68
+ onComplete?: OnCompleteFunction;
69
+ }): Promise<Promise<{
70
+ canceled: boolean;
71
+ }> | undefined>;
72
+ loopCharacterAnimation(): Promise<{
73
+ canceled: boolean;
74
+ } | undefined>;
75
+ pauseAnimation(): Promise<void | undefined>;
76
+ resumeAnimation(): Promise<void | undefined>;
77
+ showOutline(options?: {
78
+ duration?: number;
79
+ onComplete?: OnCompleteFunction;
80
+ }): Promise<Promise<{
81
+ canceled: boolean;
82
+ }> | undefined>;
83
+ hideOutline(options?: {
84
+ duration?: number;
85
+ onComplete?: OnCompleteFunction;
86
+ }): Promise<Promise<{
87
+ canceled: boolean;
88
+ }> | undefined>;
89
+ /** Updates the size of the writer instance without resetting render state */
90
+ updateDimensions({ width, height, padding }: Partial<DimensionOptions>): void;
91
+ updateColor(colorName: keyof ColorOptions, colorVal: string | null, options?: {
92
+ duration?: number;
93
+ onComplete?: OnCompleteFunction;
94
+ }): Promise<Promise<{
95
+ canceled: boolean;
96
+ }> | undefined>;
97
+ quiz(quizOptions?: Partial<QuizOptions>): Promise<Promise<void> | undefined>;
98
+ skipQuizStroke(): void;
99
+ cancelQuiz(): void;
100
+ setCharacter(char: string): Promise<void>;
101
+ _initAndMountHanziWriterRenderer(character: Character): HanziWriterRendererBase<any, any>;
102
+ getCharacterData(): Promise<Character>;
103
+ _assignOptions(options: Partial<HanziWriterOptions>): ParsedHanziWriterOptions;
104
+ /** returns a new options object with width and height filled in if missing */
105
+ _fillWidthAndHeight(options: HanziWriterOptions): ParsedHanziWriterOptions;
106
+ _withData<T>(func: () => T): Promise<T | undefined>;
107
+ _setupListeners(): void;
108
+ }