js-draw 0.1.5 → 0.1.8

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 (139) hide show
  1. package/.eslintrc.js +1 -0
  2. package/CHANGELOG.md +16 -0
  3. package/README.md +2 -2
  4. package/dist/bundle.js +1 -1
  5. package/dist/src/Color4.js +6 -2
  6. package/dist/src/Editor.d.ts +1 -0
  7. package/dist/src/Editor.js +24 -9
  8. package/dist/src/EditorImage.d.ts +8 -13
  9. package/dist/src/EditorImage.js +51 -29
  10. package/dist/src/SVGLoader.js +6 -2
  11. package/dist/src/Viewport.d.ts +10 -2
  12. package/dist/src/Viewport.js +8 -6
  13. package/dist/src/commands/Command.d.ts +9 -8
  14. package/dist/src/commands/Command.js +15 -14
  15. package/dist/src/commands/Duplicate.d.ts +14 -0
  16. package/dist/src/commands/Duplicate.js +34 -0
  17. package/dist/src/commands/Erase.d.ts +5 -2
  18. package/dist/src/commands/Erase.js +28 -9
  19. package/dist/src/commands/SerializableCommand.d.ts +13 -0
  20. package/dist/src/commands/SerializableCommand.js +28 -0
  21. package/dist/src/commands/localization.d.ts +2 -0
  22. package/dist/src/commands/localization.js +2 -0
  23. package/dist/src/components/AbstractComponent.d.ts +15 -2
  24. package/dist/src/components/AbstractComponent.js +122 -26
  25. package/dist/src/components/SVGGlobalAttributesObject.d.ts +6 -1
  26. package/dist/src/components/SVGGlobalAttributesObject.js +23 -1
  27. package/dist/src/components/Stroke.d.ts +5 -0
  28. package/dist/src/components/Stroke.js +32 -1
  29. package/dist/src/components/Text.d.ts +11 -4
  30. package/dist/src/components/Text.js +57 -3
  31. package/dist/src/components/UnknownSVGObject.d.ts +2 -0
  32. package/dist/src/components/UnknownSVGObject.js +12 -1
  33. package/dist/src/components/builders/RectangleBuilder.d.ts +3 -1
  34. package/dist/src/components/builders/RectangleBuilder.js +17 -8
  35. package/dist/src/components/util/describeComponentList.d.ts +4 -0
  36. package/dist/src/components/util/describeComponentList.js +14 -0
  37. package/dist/src/geometry/Path.d.ts +4 -1
  38. package/dist/src/geometry/Path.js +4 -0
  39. package/dist/src/rendering/Display.d.ts +3 -0
  40. package/dist/src/rendering/Display.js +13 -0
  41. package/dist/src/rendering/RenderingStyle.d.ts +24 -0
  42. package/dist/src/rendering/RenderingStyle.js +32 -0
  43. package/dist/src/rendering/caching/RenderingCacheNode.js +5 -1
  44. package/dist/src/rendering/renderers/AbstractRenderer.d.ts +1 -8
  45. package/dist/src/rendering/renderers/AbstractRenderer.js +1 -6
  46. package/dist/src/rendering/renderers/CanvasRenderer.d.ts +2 -1
  47. package/dist/src/rendering/renderers/DummyRenderer.d.ts +2 -1
  48. package/dist/src/rendering/renderers/SVGRenderer.d.ts +2 -1
  49. package/dist/src/rendering/renderers/TextOnlyRenderer.d.ts +2 -1
  50. package/dist/src/toolbar/HTMLToolbar.d.ts +1 -1
  51. package/dist/src/toolbar/HTMLToolbar.js +52 -534
  52. package/dist/src/toolbar/icons.d.ts +5 -0
  53. package/dist/src/toolbar/icons.js +186 -13
  54. package/dist/src/toolbar/localization.d.ts +4 -0
  55. package/dist/src/toolbar/localization.js +4 -0
  56. package/dist/src/toolbar/makeColorInput.d.ts +5 -0
  57. package/dist/src/toolbar/makeColorInput.js +81 -0
  58. package/dist/src/toolbar/widgets/BaseToolWidget.d.ts +12 -0
  59. package/dist/src/toolbar/widgets/BaseToolWidget.js +44 -0
  60. package/dist/src/toolbar/widgets/BaseWidget.d.ts +32 -0
  61. package/dist/src/toolbar/widgets/BaseWidget.js +148 -0
  62. package/dist/src/toolbar/widgets/EraserWidget.d.ts +6 -0
  63. package/dist/src/toolbar/widgets/EraserWidget.js +14 -0
  64. package/dist/src/toolbar/widgets/HandToolWidget.d.ts +13 -0
  65. package/dist/src/toolbar/widgets/HandToolWidget.js +133 -0
  66. package/dist/src/toolbar/widgets/PenWidget.d.ts +20 -0
  67. package/dist/src/toolbar/widgets/PenWidget.js +131 -0
  68. package/dist/src/toolbar/widgets/SelectionWidget.d.ts +11 -0
  69. package/dist/src/toolbar/widgets/SelectionWidget.js +56 -0
  70. package/dist/src/toolbar/widgets/TextToolWidget.d.ts +13 -0
  71. package/dist/src/toolbar/widgets/TextToolWidget.js +72 -0
  72. package/dist/src/tools/Pen.js +1 -1
  73. package/dist/src/tools/PipetteTool.d.ts +20 -0
  74. package/dist/src/tools/PipetteTool.js +40 -0
  75. package/dist/src/tools/SelectionTool.d.ts +2 -0
  76. package/dist/src/tools/SelectionTool.js +41 -23
  77. package/dist/src/tools/TextTool.js +1 -1
  78. package/dist/src/tools/ToolController.d.ts +3 -1
  79. package/dist/src/tools/ToolController.js +4 -0
  80. package/dist/src/tools/localization.d.ts +2 -1
  81. package/dist/src/tools/localization.js +3 -2
  82. package/dist/src/types.d.ts +7 -2
  83. package/dist/src/types.js +1 -0
  84. package/jest.config.js +2 -0
  85. package/package.json +6 -6
  86. package/src/Color4.ts +9 -3
  87. package/src/Editor.ts +29 -12
  88. package/src/EditorImage.test.ts +5 -5
  89. package/src/EditorImage.ts +61 -20
  90. package/src/SVGLoader.ts +9 -3
  91. package/src/Viewport.ts +7 -6
  92. package/src/commands/Command.ts +21 -19
  93. package/src/commands/Duplicate.ts +49 -0
  94. package/src/commands/Erase.ts +34 -13
  95. package/src/commands/SerializableCommand.ts +41 -0
  96. package/src/commands/localization.ts +5 -0
  97. package/src/components/AbstractComponent.ts +168 -26
  98. package/src/components/SVGGlobalAttributesObject.ts +34 -2
  99. package/src/components/Stroke.test.ts +53 -0
  100. package/src/components/Stroke.ts +37 -2
  101. package/src/components/Text.test.ts +38 -0
  102. package/src/components/Text.ts +80 -5
  103. package/src/components/UnknownSVGObject.test.ts +10 -0
  104. package/src/components/UnknownSVGObject.ts +15 -1
  105. package/src/components/builders/FreehandLineBuilder.ts +2 -1
  106. package/src/components/builders/RectangleBuilder.ts +23 -8
  107. package/src/components/util/describeComponentList.ts +18 -0
  108. package/src/geometry/Path.ts +8 -1
  109. package/src/rendering/Display.ts +17 -1
  110. package/src/rendering/RenderingStyle.test.ts +68 -0
  111. package/src/rendering/RenderingStyle.ts +46 -0
  112. package/src/rendering/caching/RenderingCache.test.ts +1 -1
  113. package/src/rendering/caching/RenderingCacheNode.ts +6 -1
  114. package/src/rendering/renderers/AbstractRenderer.ts +1 -15
  115. package/src/rendering/renderers/CanvasRenderer.ts +2 -1
  116. package/src/rendering/renderers/DummyRenderer.ts +2 -1
  117. package/src/rendering/renderers/SVGRenderer.ts +2 -1
  118. package/src/rendering/renderers/TextOnlyRenderer.ts +2 -1
  119. package/src/toolbar/HTMLToolbar.ts +58 -660
  120. package/src/toolbar/icons.ts +205 -13
  121. package/src/toolbar/localization.ts +10 -2
  122. package/src/toolbar/makeColorInput.ts +105 -0
  123. package/src/toolbar/toolbar.css +116 -78
  124. package/src/toolbar/widgets/BaseToolWidget.ts +53 -0
  125. package/src/toolbar/widgets/BaseWidget.ts +175 -0
  126. package/src/toolbar/widgets/EraserWidget.ts +16 -0
  127. package/src/toolbar/widgets/HandToolWidget.ts +186 -0
  128. package/src/toolbar/widgets/PenWidget.ts +165 -0
  129. package/src/toolbar/widgets/SelectionWidget.ts +72 -0
  130. package/src/toolbar/widgets/TextToolWidget.ts +90 -0
  131. package/src/tools/Pen.ts +1 -1
  132. package/src/tools/PipetteTool.ts +56 -0
  133. package/src/tools/SelectionTool.test.ts +2 -4
  134. package/src/tools/SelectionTool.ts +47 -27
  135. package/src/tools/TextTool.ts +1 -1
  136. package/src/tools/ToolController.ts +10 -6
  137. package/src/tools/UndoRedoShortcut.test.ts +1 -1
  138. package/src/tools/localization.ts +6 -3
  139. package/src/types.ts +12 -1
@@ -1,5 +1,6 @@
1
1
  import { Bezier } from 'bezier-js';
2
- import { RenderingStyle, RenderablePathSpec } from '../rendering/renderers/AbstractRenderer';
2
+ import { RenderablePathSpec } from '../rendering/renderers/AbstractRenderer';
3
+ import RenderingStyle from '../rendering/RenderingStyle';
3
4
  import LineSegment2 from './LineSegment2';
4
5
  import Mat33 from './Mat33';
5
6
  import Rect2 from './Rect2';
@@ -50,7 +51,9 @@ export default class Path {
50
51
  static fromRenderable(renderable: RenderablePathSpec): Path;
51
52
  toRenderable(fill: RenderingStyle): RenderablePathSpec;
52
53
  toString(): string;
54
+ serialize(): string;
53
55
  static toString(startPoint: Point2, parts: PathCommand[]): string;
54
56
  static fromString(pathString: string): Path;
57
+ static empty: Path;
55
58
  }
56
59
  export {};
@@ -203,6 +203,9 @@ export default class Path {
203
203
  toString() {
204
204
  return Path.toString(this.startPoint, this.parts);
205
205
  }
206
+ serialize() {
207
+ return this.toString();
208
+ }
206
209
  static toString(startPoint, parts) {
207
210
  const result = [];
208
211
  const toRoundedString = (num) => {
@@ -445,3 +448,4 @@ export default class Path {
445
448
  return new Path(startPos !== null && startPos !== void 0 ? startPos : Vec2.zero, commands);
446
449
  }
447
450
  }
451
+ Path.empty = new Path(Vec2.zero, []);
@@ -1,6 +1,8 @@
1
1
  import AbstractRenderer from './renderers/AbstractRenderer';
2
2
  import { Editor } from '../Editor';
3
+ import { Point2 } from '../geometry/Vec2';
3
4
  import RenderingCache from './caching/RenderingCache';
5
+ import Color4 from '../Color4';
4
6
  export declare enum RenderingMode {
5
7
  DummyRenderer = 0,
6
8
  CanvasRenderer = 1
@@ -18,6 +20,7 @@ export default class Display {
18
20
  get width(): number;
19
21
  get height(): number;
20
22
  getCache(): RenderingCache;
23
+ getColorAt: (_screenPos: Point2) => Color4 | null;
21
24
  private initializeCanvasRendering;
22
25
  private initializeTextRendering;
23
26
  startRerender(): AbstractRenderer;
@@ -4,6 +4,7 @@ import DummyRenderer from './renderers/DummyRenderer';
4
4
  import { Vec2 } from '../geometry/Vec2';
5
5
  import RenderingCache from './caching/RenderingCache';
6
6
  import TextOnlyRenderer from './renderers/TextOnlyRenderer';
7
+ import Color4 from '../Color4';
7
8
  export var RenderingMode;
8
9
  (function (RenderingMode) {
9
10
  RenderingMode[RenderingMode["DummyRenderer"] = 0] = "DummyRenderer";
@@ -14,6 +15,9 @@ export default class Display {
14
15
  constructor(editor, mode, parent) {
15
16
  this.editor = editor;
16
17
  this.parent = parent;
18
+ this.getColorAt = (_screenPos) => {
19
+ return null;
20
+ };
17
21
  if (mode === RenderingMode.CanvasRenderer) {
18
22
  this.initializeCanvasRendering();
19
23
  }
@@ -106,6 +110,15 @@ export default class Display {
106
110
  this.flattenCallback = () => {
107
111
  dryInkCtx.drawImage(wetInkCanvas, 0, 0);
108
112
  };
113
+ this.getColorAt = (screenPos) => {
114
+ const pixel = dryInkCtx.getImageData(screenPos.x, screenPos.y, 1, 1);
115
+ const data = pixel === null || pixel === void 0 ? void 0 : pixel.data;
116
+ if (data) {
117
+ const color = Color4.ofRGBA(data[0] / 255, data[1] / 255, data[2] / 255, data[3] / 255);
118
+ return color;
119
+ }
120
+ return null;
121
+ };
109
122
  }
110
123
  initializeTextRendering() {
111
124
  const textRendererOutputContainer = document.createElement('div');
@@ -0,0 +1,24 @@
1
+ import Color4 from '../Color4';
2
+ interface RenderingStyle {
3
+ fill: Color4;
4
+ stroke?: {
5
+ color: Color4;
6
+ width: number;
7
+ };
8
+ }
9
+ export default RenderingStyle;
10
+ export declare const stylesEqual: (a: RenderingStyle, b: RenderingStyle) => boolean;
11
+ export declare const styleToJSON: (style: RenderingStyle) => {
12
+ fill: string;
13
+ stroke: {
14
+ color: string;
15
+ width: number;
16
+ } | undefined;
17
+ };
18
+ export declare const styleFromJSON: (json: Record<string, any>) => {
19
+ fill: Color4;
20
+ stroke: {
21
+ color: Color4;
22
+ width: any;
23
+ } | undefined;
24
+ };
@@ -0,0 +1,32 @@
1
+ import Color4 from '../Color4';
2
+ export const stylesEqual = (a, b) => {
3
+ var _a, _b, _c, _d, _e, _f;
4
+ const result = a === b || (a.fill.eq(b.fill)
5
+ && (a.stroke == undefined) === (b.stroke == undefined)
6
+ && ((_d = (_b = (_a = a.stroke) === null || _a === void 0 ? void 0 : _a.color) === null || _b === void 0 ? void 0 : _b.eq((_c = b.stroke) === null || _c === void 0 ? void 0 : _c.color)) !== null && _d !== void 0 ? _d : true)
7
+ && ((_e = a.stroke) === null || _e === void 0 ? void 0 : _e.width) === ((_f = b.stroke) === null || _f === void 0 ? void 0 : _f.width));
8
+ // Map undefined/null -> false
9
+ return result !== null && result !== void 0 ? result : false;
10
+ };
11
+ // Returns an object that can be converted to a JSON string with
12
+ // JSON.stringify.
13
+ export const styleToJSON = (style) => {
14
+ const stroke = !style.stroke ? undefined : {
15
+ color: style.stroke.color.toHexString(),
16
+ width: style.stroke.width,
17
+ };
18
+ return {
19
+ fill: style.fill.toHexString(),
20
+ stroke,
21
+ };
22
+ };
23
+ export const styleFromJSON = (json) => {
24
+ const stroke = json.stroke ? {
25
+ color: Color4.fromHex(json.stroke.color),
26
+ width: json.stroke.width,
27
+ } : undefined;
28
+ return {
29
+ fill: Color4.fromHex(json.fill),
30
+ stroke,
31
+ };
32
+ };
@@ -44,6 +44,10 @@ export default class RenderingCacheNode {
44
44
  generateChildren() {
45
45
  if (this.instantiatedChildren.length === 0) {
46
46
  const childRects = this.region.divideIntoGrid(cacheDivisionSize, cacheDivisionSize);
47
+ if (this.region.size.x === 0 || this.region.size.y === 0) {
48
+ console.warn('Cache element has zero size! Not generating children.');
49
+ return;
50
+ }
47
51
  for (const rect of childRects) {
48
52
  const child = new RenderingCacheNode(rect, this.cacheState);
49
53
  child.parent = this;
@@ -283,7 +287,7 @@ export default class RenderingCacheNode {
283
287
  }
284
288
  checkRep() {
285
289
  if (this.instantiatedChildren.length !== cacheDivisionSize * cacheDivisionSize && this.instantiatedChildren.length !== 0) {
286
- throw new Error('Repcheck: Wrong number of children');
290
+ throw new Error(`Repcheck: Wrong number of children. Got ${this.instantiatedChildren.length}`);
287
291
  }
288
292
  if (this.renderedIds[1] !== undefined && this.renderedIds[0] >= this.renderedIds[1]) {
289
293
  console.error(this.renderedIds);
@@ -1,4 +1,3 @@
1
- import Color4 from '../../Color4';
2
1
  import { LoadSaveDataTable } from '../../components/AbstractComponent';
3
2
  import { TextStyle } from '../../components/Text';
4
3
  import Mat33 from '../../geometry/Mat33';
@@ -6,13 +5,7 @@ import { PathCommand } from '../../geometry/Path';
6
5
  import Rect2 from '../../geometry/Rect2';
7
6
  import { Point2, Vec2 } from '../../geometry/Vec2';
8
7
  import Viewport from '../../Viewport';
9
- export interface RenderingStyle {
10
- fill: Color4;
11
- stroke?: {
12
- color: Color4;
13
- width: number;
14
- };
15
- }
8
+ import RenderingStyle from '../RenderingStyle';
16
9
  export interface RenderablePathSpec {
17
10
  startPoint: Point2;
18
11
  commands: PathCommand[];
@@ -1,11 +1,6 @@
1
1
  import Path, { PathCommandType } from '../../geometry/Path';
2
2
  import { Vec2 } from '../../geometry/Vec2';
3
- const stylesEqual = (a, b) => {
4
- var _a, _b, _c, _d, _e;
5
- return a === b || (a.fill.eq(b.fill)
6
- && ((_b = (_a = a.stroke) === null || _a === void 0 ? void 0 : _a.color) === null || _b === void 0 ? void 0 : _b.eq((_c = b.stroke) === null || _c === void 0 ? void 0 : _c.color))
7
- && ((_d = a.stroke) === null || _d === void 0 ? void 0 : _d.width) === ((_e = b.stroke) === null || _e === void 0 ? void 0 : _e.width));
8
- };
3
+ import { stylesEqual } from '../RenderingStyle';
9
4
  export default class AbstractRenderer {
10
5
  constructor(viewport) {
11
6
  this.viewport = viewport;
@@ -4,7 +4,8 @@ import Rect2 from '../../geometry/Rect2';
4
4
  import { Point2, Vec2 } from '../../geometry/Vec2';
5
5
  import Vec3 from '../../geometry/Vec3';
6
6
  import Viewport from '../../Viewport';
7
- import AbstractRenderer, { RenderablePathSpec, RenderingStyle } from './AbstractRenderer';
7
+ import RenderingStyle from '../RenderingStyle';
8
+ import AbstractRenderer, { RenderablePathSpec } from './AbstractRenderer';
8
9
  export default class CanvasRenderer extends AbstractRenderer {
9
10
  private ctx;
10
11
  private ignoreObjectsAboveLevel;
@@ -4,7 +4,8 @@ import Rect2 from '../../geometry/Rect2';
4
4
  import { Point2, Vec2 } from '../../geometry/Vec2';
5
5
  import Vec3 from '../../geometry/Vec3';
6
6
  import Viewport from '../../Viewport';
7
- import AbstractRenderer, { RenderingStyle } from './AbstractRenderer';
7
+ import RenderingStyle from '../RenderingStyle';
8
+ import AbstractRenderer from './AbstractRenderer';
8
9
  export default class DummyRenderer extends AbstractRenderer {
9
10
  clearedCount: number;
10
11
  renderedPathCount: number;
@@ -4,7 +4,8 @@ import Mat33 from '../../geometry/Mat33';
4
4
  import Rect2 from '../../geometry/Rect2';
5
5
  import { Point2, Vec2 } from '../../geometry/Vec2';
6
6
  import Viewport from '../../Viewport';
7
- import AbstractRenderer, { RenderingStyle } from './AbstractRenderer';
7
+ import RenderingStyle from '../RenderingStyle';
8
+ import AbstractRenderer from './AbstractRenderer';
8
9
  export default class SVGRenderer extends AbstractRenderer {
9
10
  private elem;
10
11
  private currentPath;
@@ -4,7 +4,8 @@ import Rect2 from '../../geometry/Rect2';
4
4
  import Vec3 from '../../geometry/Vec3';
5
5
  import Viewport from '../../Viewport';
6
6
  import { TextRendererLocalization } from '../localization';
7
- import AbstractRenderer, { RenderingStyle } from './AbstractRenderer';
7
+ import RenderingStyle from '../RenderingStyle';
8
+ import AbstractRenderer from './AbstractRenderer';
8
9
  export default class TextOnlyRenderer extends AbstractRenderer {
9
10
  private localizationTable;
10
11
  private descriptionBuilder;
@@ -1,11 +1,11 @@
1
1
  import Editor from '../Editor';
2
2
  import { ToolbarLocalization } from './localization';
3
3
  import { ActionButtonIcon } from './types';
4
+ export declare const toolbarCSSPrefix = "toolbar-";
4
5
  export default class HTMLToolbar {
5
6
  private editor;
6
7
  private localizationTable;
7
8
  private container;
8
- private penTypes;
9
9
  constructor(editor: Editor, parent: HTMLElement, localizationTable?: ToolbarLocalization);
10
10
  setupColorPickers(): void;
11
11
  addActionButton(title: string | ActionButtonIcon, command: () => void, parent?: Element): HTMLButtonElement;