js-draw 1.22.0 → 1.23.1

Sign up to get free protection for your applications and to get access to all the features.
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
  /**