js-draw 1.22.0 → 1.23.1

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 (63) hide show
  1. package/README.md +1 -1
  2. package/dist/bundle.js +1 -1
  3. package/dist/cjs/Editor.d.ts +1 -3
  4. package/dist/cjs/Editor.js +2 -4
  5. package/dist/cjs/SVGLoader/SVGLoader.js +2 -0
  6. package/dist/cjs/Viewport.d.ts +1 -1
  7. package/dist/cjs/Viewport.js +1 -1
  8. package/dist/cjs/components/AbstractComponent.d.ts +1 -1
  9. package/dist/cjs/components/AbstractComponent.js +1 -1
  10. package/dist/cjs/components/builders/ArrowBuilder.d.ts +1 -1
  11. package/dist/cjs/components/builders/ArrowBuilder.js +1 -1
  12. package/dist/cjs/image/EditorImage.d.ts +30 -7
  13. package/dist/cjs/image/EditorImage.js +30 -7
  14. package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +2 -25
  15. package/dist/cjs/rendering/renderers/CanvasRenderer.js +2 -25
  16. package/dist/cjs/rendering/renderers/SVGRenderer.js +2 -2
  17. package/dist/cjs/toolbar/AbstractToolbar.d.ts +19 -0
  18. package/dist/cjs/toolbar/AbstractToolbar.js +19 -0
  19. package/dist/cjs/toolbar/IconProvider.d.ts +5 -1
  20. package/dist/cjs/toolbar/IconProvider.js +112 -146
  21. package/dist/cjs/toolbar/localization.js +2 -2
  22. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +1 -1
  23. package/dist/cjs/toolbar/widgets/BaseWidget.js +1 -1
  24. package/dist/cjs/tools/PanZoom.js +1 -1
  25. package/dist/cjs/tools/Pen.d.ts +13 -0
  26. package/dist/cjs/tools/Pen.js +13 -0
  27. package/dist/cjs/tools/lib.d.ts +1 -0
  28. package/dist/cjs/tools/lib.js +3 -1
  29. package/dist/cjs/util/cloneElementWithStyles.js +1 -1
  30. package/dist/cjs/util/createElement.d.ts +62 -0
  31. package/dist/cjs/util/createElement.js +53 -0
  32. package/dist/cjs/version.js +1 -1
  33. package/dist/mjs/Editor.d.ts +1 -3
  34. package/dist/mjs/Editor.mjs +2 -4
  35. package/dist/mjs/SVGLoader/SVGLoader.mjs +2 -0
  36. package/dist/mjs/Viewport.d.ts +1 -1
  37. package/dist/mjs/Viewport.mjs +1 -1
  38. package/dist/mjs/components/AbstractComponent.d.ts +1 -1
  39. package/dist/mjs/components/AbstractComponent.mjs +1 -1
  40. package/dist/mjs/components/builders/ArrowBuilder.d.ts +1 -1
  41. package/dist/mjs/components/builders/ArrowBuilder.mjs +1 -1
  42. package/dist/mjs/image/EditorImage.d.ts +30 -7
  43. package/dist/mjs/image/EditorImage.mjs +30 -7
  44. package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +2 -25
  45. package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +2 -25
  46. package/dist/mjs/rendering/renderers/SVGRenderer.mjs +2 -2
  47. package/dist/mjs/toolbar/AbstractToolbar.d.ts +19 -0
  48. package/dist/mjs/toolbar/AbstractToolbar.mjs +19 -0
  49. package/dist/mjs/toolbar/IconProvider.d.ts +5 -1
  50. package/dist/mjs/toolbar/IconProvider.mjs +112 -146
  51. package/dist/mjs/toolbar/localization.mjs +2 -2
  52. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +1 -1
  53. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +1 -1
  54. package/dist/mjs/tools/PanZoom.mjs +1 -1
  55. package/dist/mjs/tools/Pen.d.ts +13 -0
  56. package/dist/mjs/tools/Pen.mjs +13 -0
  57. package/dist/mjs/tools/lib.d.ts +1 -0
  58. package/dist/mjs/tools/lib.mjs +1 -0
  59. package/dist/mjs/util/cloneElementWithStyles.mjs +1 -1
  60. package/dist/mjs/util/createElement.d.ts +62 -0
  61. package/dist/mjs/util/createElement.mjs +47 -0
  62. package/dist/mjs/version.mjs +1 -1
  63. package/package.json +4 -4
@@ -100,7 +100,7 @@ export class Viewport {
100
100
  /**
101
101
  * Snaps `canvasPos` to the nearest grid cell corner.
102
102
  *
103
- * @see {@link getGridSize} and {@link getScaleFactorToNearestPowerOf}.
103
+ * @see {@link getGridSize}.
104
104
  */
105
105
  snapToGrid(canvasPos) {
106
106
  const scaleFactor = this.getScaleFactorToNearestPowerOf(2);
@@ -122,7 +122,7 @@ export default abstract class AbstractComponent {
122
122
  * updates the editor.
123
123
  *
124
124
  * The transformed component is also moved to the top (use
125
- * {@link AbstractComponent.setZIndexAndTransformBy} to avoid this behavior).
125
+ * {@link AbstractComponent#setZIndexAndTransformBy} to avoid this behavior).
126
126
  */
127
127
  transformBy(affineTransfm: Mat33): SerializableCommand;
128
128
  setZIndex(newZIndex: number): SerializableCommand;
@@ -156,7 +156,7 @@ class AbstractComponent {
156
156
  * updates the editor.
157
157
  *
158
158
  * The transformed component is also moved to the top (use
159
- * {@link AbstractComponent.setZIndexAndTransformBy} to avoid this behavior).
159
+ * {@link AbstractComponent#setZIndexAndTransformBy} to avoid this behavior).
160
160
  */
161
161
  transformBy(affineTransfm) {
162
162
  return new AbstractComponent.TransformElementCommand(affineTransfm, this.getId(), this);
@@ -5,7 +5,7 @@ import Viewport from '../../Viewport';
5
5
  import AbstractComponent from '../AbstractComponent';
6
6
  import { ComponentBuilder, ComponentBuilderFactory } from './types';
7
7
  /**
8
- * Creates a stroke builder that generates arrows circles.
8
+ * Creates a stroke builder that generates arrows.
9
9
  *
10
10
  * Example:
11
11
  * [[include:doc-pages/inline-examples/changing-pen-types.md]]
@@ -2,7 +2,7 @@ import { Path, PathCommandType } from '@js-draw/math';
2
2
  import Stroke from '../Stroke.mjs';
3
3
  import makeSnapToGridAutocorrect from './autocorrect/makeSnapToGridAutocorrect.mjs';
4
4
  /**
5
- * Creates a stroke builder that generates arrows circles.
5
+ * Creates a stroke builder that generates arrows.
6
6
  *
7
7
  * Example:
8
8
  * [[include:doc-pages/inline-examples/changing-pen-types.md]]
@@ -22,7 +22,20 @@ export type EditorImageNotifier = EventDispatcher<EditorImageEventType, {
22
22
  */
23
23
  export type PreRenderComponentCallback = (component: AbstractComponent, componentsProcessed: number, totalComponents: number) => Promise<boolean>;
24
24
  /**
25
- * Handles lookup/storage of elements in the image.
25
+ * @summary Handles lookup/storage of elements in the image.
26
+ *
27
+ * `js-draw` images are made up of a collection of {@link AbstractComponent}s (which
28
+ * includes {@link Stroke}s, {@link TextComponent}s, etc.). An `EditorImage`
29
+ * is the data structure that stores these components.
30
+ *
31
+ * Here's how to do a few common operations:
32
+ * - **Get all components in a {@link @js-draw/math!Rect2 | Rect2}**:
33
+ * {@link EditorImage.getElementsIntersectingRegion}.
34
+ * - **Draw an `EditorImage` onto a canvas/SVG**: {@link EditorImage.render}.
35
+ * - **Adding a new component**: {@link EditorImage.addElement}.
36
+ *
37
+ * **Example**:
38
+ * [[include:doc-pages/inline-examples/image-add-and-lookup.md]]
26
39
  */
27
40
  export default class EditorImage {
28
41
  private root;
@@ -40,10 +53,13 @@ export default class EditorImage {
40
53
  /** @internal */
41
54
  renderWithCache(screenRenderer: AbstractRenderer, cache: RenderingCache, viewport: Viewport): void;
42
55
  /**
43
- * Renders all nodes visible from `viewport` (or all nodes if `viewport = null`).
56
+ * Renders this image to the given `renderer`.
44
57
  *
45
- * `viewport` is used to improve rendering performance. If given, it must match
46
- * the viewport used by the `renderer` (if any).
58
+ * If `viewport` is non-null, only components that can be seen from that viewport
59
+ * will be rendered. If `viewport` is `null`, **all** components are rendered.
60
+ *
61
+ * **Example**:
62
+ * [[include:doc-pages/inline-examples/canvas-renderer.md]]
47
63
  */
48
64
  render(renderer: AbstractRenderer, viewport: Viewport | null): void;
49
65
  /**
@@ -63,14 +79,21 @@ export default class EditorImage {
63
79
  */
64
80
  renderAll(renderer: AbstractRenderer): void;
65
81
  /**
66
- * @returns all elements in the image, sorted by z-index. This can be slow for large images.
82
+ * @returns all elements in the image, sorted by z-index (low to high).
67
83
  *
68
- * Does not include background elements. See {@link getBackgroundComponents}.
84
+ * This can be slow for large images. If you only need all elemenst in part of the image,
85
+ * consider using {@link getElementsIntersectingRegion} instead.
86
+ *
87
+ * **Note**: The result does not include background elements. See {@link getBackgroundComponents}.
69
88
  */
70
89
  getAllElements(): AbstractComponent[];
71
90
  /** Returns the number of elements added to this image. @internal */
72
91
  estimateNumElements(): number;
73
- /** @returns a list of `AbstractComponent`s intersecting `region`, sorted by z-index. */
92
+ /**
93
+ * @returns a list of `AbstractComponent`s intersecting `region`, sorted by increasing z-index.
94
+ *
95
+ * Components in the background layer are only included if `includeBackground` is `true`.
96
+ */
74
97
  getElementsIntersectingRegion(region: Rect2, includeBackground?: boolean): AbstractComponent[];
75
98
  /** Called whenever (just after) an element is completely removed. @internal */
76
99
  onDestroyElement(elem: AbstractComponent): void;
@@ -21,7 +21,20 @@ export var EditorImageEventType;
21
21
  })(EditorImageEventType || (EditorImageEventType = {}));
22
22
  let debugMode = false;
23
23
  /**
24
- * Handles lookup/storage of elements in the image.
24
+ * @summary Handles lookup/storage of elements in the image.
25
+ *
26
+ * `js-draw` images are made up of a collection of {@link AbstractComponent}s (which
27
+ * includes {@link Stroke}s, {@link TextComponent}s, etc.). An `EditorImage`
28
+ * is the data structure that stores these components.
29
+ *
30
+ * Here's how to do a few common operations:
31
+ * - **Get all components in a {@link @js-draw/math!Rect2 | Rect2}**:
32
+ * {@link EditorImage.getElementsIntersectingRegion}.
33
+ * - **Draw an `EditorImage` onto a canvas/SVG**: {@link EditorImage.render}.
34
+ * - **Adding a new component**: {@link EditorImage.addElement}.
35
+ *
36
+ * **Example**:
37
+ * [[include:doc-pages/inline-examples/image-add-and-lookup.md]]
25
38
  */
26
39
  class EditorImage {
27
40
  // @internal
@@ -80,10 +93,13 @@ class EditorImage {
80
93
  }
81
94
  }
82
95
  /**
83
- * Renders all nodes visible from `viewport` (or all nodes if `viewport = null`).
96
+ * Renders this image to the given `renderer`.
84
97
  *
85
- * `viewport` is used to improve rendering performance. If given, it must match
86
- * the viewport used by the `renderer` (if any).
98
+ * If `viewport` is non-null, only components that can be seen from that viewport
99
+ * will be rendered. If `viewport` is `null`, **all** components are rendered.
100
+ *
101
+ * **Example**:
102
+ * [[include:doc-pages/inline-examples/canvas-renderer.md]]
87
103
  */
88
104
  render(renderer, viewport) {
89
105
  this.background.render(renderer, viewport?.visibleRect);
@@ -114,9 +130,12 @@ class EditorImage {
114
130
  this.render(renderer, null);
115
131
  }
116
132
  /**
117
- * @returns all elements in the image, sorted by z-index. This can be slow for large images.
133
+ * @returns all elements in the image, sorted by z-index (low to high).
118
134
  *
119
- * Does not include background elements. See {@link getBackgroundComponents}.
135
+ * This can be slow for large images. If you only need all elemenst in part of the image,
136
+ * consider using {@link getElementsIntersectingRegion} instead.
137
+ *
138
+ * **Note**: The result does not include background elements. See {@link getBackgroundComponents}.
120
139
  */
121
140
  getAllElements() {
122
141
  const leaves = this.root.getLeaves();
@@ -127,7 +146,11 @@ class EditorImage {
127
146
  estimateNumElements() {
128
147
  return this.componentCount;
129
148
  }
130
- /** @returns a list of `AbstractComponent`s intersecting `region`, sorted by z-index. */
149
+ /**
150
+ * @returns a list of `AbstractComponent`s intersecting `region`, sorted by increasing z-index.
151
+ *
152
+ * Components in the background layer are only included if `includeBackground` is `true`.
153
+ */
131
154
  getElementsIntersectingRegion(region, includeBackground = false) {
132
155
  let leaves = this.root.getLeavesIntersectingRegion(region);
133
156
  if (includeBackground) {
@@ -7,31 +7,8 @@ import RenderablePathSpec from '../RenderablePathSpec';
7
7
  /**
8
8
  * Renders onto a `CanvasRenderingContext2D`.
9
9
  *
10
- * @example
11
- * ```ts,runnable
12
- * import {Editor,CanvasRenderer} from 'js-draw';
13
- *
14
- * // Create an editor and load initial data -- don't add to the body (hidden editor).
15
- * const editor = new Editor(document.createElement('div'));
16
- * await editor.loadFromSVG('<svg><path d="m0,0 l100,5 l-50,60 l30,20 z" fill="green"/></svg>');
17
- * ---visible---
18
- * // Given some editor.
19
- * // Set up the canvas to be drawn onto.
20
- * const canvas = document.createElement('canvas');
21
- * const ctx = canvas.getContext('2d');
22
- *
23
- * // Ensure that the canvas can fit the entire rendering
24
- * const viewport = editor.image.getImportExportViewport();
25
- * canvas.width = viewport.getScreenRectSize().x;
26
- * canvas.height = viewport.getScreenRectSize().y;
27
- *
28
- * // Render editor.image onto the renderer
29
- * const renderer = new CanvasRenderer(ctx, viewport);
30
- * editor.image.render(renderer, viewport);
31
- *
32
- * // Add the rendered canvas to the document.
33
- * document.body.appendChild(canvas);
34
- * ```
10
+ * **Example**:
11
+ * [[include:doc-pages/inline-examples/canvas-renderer.md]]
35
12
  */
36
13
  export default class CanvasRenderer extends AbstractRenderer {
37
14
  private ctx;
@@ -5,31 +5,8 @@ import { visualEquivalent } from '../RenderablePathSpec.mjs';
5
5
  /**
6
6
  * Renders onto a `CanvasRenderingContext2D`.
7
7
  *
8
- * @example
9
- * ```ts,runnable
10
- * import {Editor,CanvasRenderer} from 'js-draw';
11
- *
12
- * // Create an editor and load initial data -- don't add to the body (hidden editor).
13
- * const editor = new Editor(document.createElement('div'));
14
- * await editor.loadFromSVG('<svg><path d="m0,0 l100,5 l-50,60 l30,20 z" fill="green"/></svg>');
15
- * ---visible---
16
- * // Given some editor.
17
- * // Set up the canvas to be drawn onto.
18
- * const canvas = document.createElement('canvas');
19
- * const ctx = canvas.getContext('2d');
20
- *
21
- * // Ensure that the canvas can fit the entire rendering
22
- * const viewport = editor.image.getImportExportViewport();
23
- * canvas.width = viewport.getScreenRectSize().x;
24
- * canvas.height = viewport.getScreenRectSize().y;
25
- *
26
- * // Render editor.image onto the renderer
27
- * const renderer = new CanvasRenderer(ctx, viewport);
28
- * editor.image.render(renderer, viewport);
29
- *
30
- * // Add the rendered canvas to the document.
31
- * document.body.appendChild(canvas);
32
- * ```
8
+ * **Example**:
9
+ * [[include:doc-pages/inline-examples/canvas-renderer.md]]
33
10
  */
34
11
  export default class CanvasRenderer extends AbstractRenderer {
35
12
  /**
@@ -43,7 +43,7 @@ export default class SVGRenderer extends AbstractRenderer {
43
43
  if (!this.elem.querySelector(`#${renderedStylesheetId}`)) {
44
44
  // Default to rounded strokes.
45
45
  const styleSheet = document.createElementNS('http://www.w3.org/2000/svg', 'style');
46
- styleSheet.innerHTML = `
46
+ styleSheet.appendChild(document.createTextNode(`
47
47
  path {
48
48
  stroke-linecap: round;
49
49
  stroke-linejoin: round;
@@ -52,7 +52,7 @@ export default class SVGRenderer extends AbstractRenderer {
52
52
  text {
53
53
  white-space: pre;
54
54
  }
55
- `.replace(/\s+/g, '');
55
+ `.replace(/\s+/g, '')));
56
56
  styleSheet.setAttribute('id', renderedStylesheetId);
57
57
  this.elem.appendChild(styleSheet);
58
58
  }
@@ -110,6 +110,25 @@ export default abstract class AbstractToolbar {
110
110
  * as being the value of `mustBeToplevel`.
111
111
  *
112
112
  * @return The added button.
113
+ *
114
+ * **Example**:
115
+ * ```ts,runnable
116
+ * import { Editor } from 'js-draw';
117
+ * const editor = new Editor(document.body);
118
+ * const toolbar = editor.addToolbar();
119
+ *
120
+ * function makeTrashIcon() {
121
+ * const container = document.createElement('div');
122
+ * container.textContent = '🗑️';
123
+ * return container;
124
+ * }
125
+ *
126
+ * toolbar.addActionButton({
127
+ * icon: makeTrashIcon(), // can be any Element not in the DOM
128
+ * label: 'Delete all',
129
+ * }, () => {
130
+ * alert('to-do!');
131
+ * });
113
132
  */
114
133
  addActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
115
134
  /**
@@ -264,6 +264,25 @@ class AbstractToolbar {
264
264
  * as being the value of `mustBeToplevel`.
265
265
  *
266
266
  * @return The added button.
267
+ *
268
+ * **Example**:
269
+ * ```ts,runnable
270
+ * import { Editor } from 'js-draw';
271
+ * const editor = new Editor(document.body);
272
+ * const toolbar = editor.addToolbar();
273
+ *
274
+ * function makeTrashIcon() {
275
+ * const container = document.createElement('div');
276
+ * container.textContent = '🗑️';
277
+ * return container;
278
+ * }
279
+ *
280
+ * toolbar.addActionButton({
281
+ * icon: makeTrashIcon(), // can be any Element not in the DOM
282
+ * label: 'Delete all',
283
+ * }, () => {
284
+ * alert('to-do!');
285
+ * });
267
286
  */
268
287
  addActionButton(title, command, options = true) {
269
288
  const widget = this.makeActionButton(title, command, options);
@@ -80,9 +80,13 @@ export default class IconProvider {
80
80
  * @returns An object with both the definition of a checkerboard pattern and the syntax to
81
81
  * reference that pattern. The defs provided by this function should be wrapped within a
82
82
  * `<defs></defs>` element.
83
+ *
84
+ * **Note**: This function's return value includes both `patternDefElement` (which returns
85
+ * an Element) and a (deprecated) `patternDef` string. Avoid using the `patternDef` result.
83
86
  */
84
87
  protected makeCheckerboardPattern(): {
85
- patternDef: string;
88
+ patternDefElement: SVGElement;
89
+ readonly patternDef: string;
86
90
  patternRef: string;
87
91
  };
88
92
  /**