js-draw 1.3.0 → 1.4.0
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.
- package/README.md +1 -1
- package/dist/Editor.css +55 -13
- package/dist/bundle.js +2 -2
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/Editor.d.ts +36 -3
- package/dist/cjs/Editor.js +63 -26
- package/dist/cjs/SVGLoader.js +37 -22
- package/dist/cjs/commands/Erase.js +1 -1
- package/dist/cjs/commands/UnresolvedCommand.d.ts +1 -1
- package/dist/cjs/components/AbstractComponent.d.ts +1 -1
- package/dist/cjs/components/AbstractComponent.js +1 -1
- package/dist/cjs/components/BackgroundComponent.d.ts +1 -1
- package/dist/cjs/components/BackgroundComponent.js +3 -2
- package/dist/cjs/{EditorImage.d.ts → image/EditorImage.d.ts} +30 -8
- package/dist/cjs/{EditorImage.js → image/EditorImage.js} +51 -7
- package/dist/cjs/image/export/editorImageToSVG.d.ts +8 -0
- package/dist/cjs/image/export/editorImageToSVG.js +49 -0
- package/dist/cjs/image/export/setExportedSVGSize.d.ts +6 -0
- package/dist/cjs/image/export/setExportedSVGSize.js +25 -0
- package/dist/cjs/image/lib.d.ts +1 -0
- package/dist/cjs/image/lib.js +8 -0
- package/dist/cjs/lib.d.ts +1 -1
- package/dist/cjs/lib.js +2 -3
- package/dist/cjs/localizations/comments.d.ts +6 -0
- package/dist/cjs/localizations/comments.js +10 -0
- package/dist/cjs/localizations/es.js +68 -48
- package/dist/cjs/rendering/caching/RenderingCache.d.ts +1 -1
- package/dist/cjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
- package/dist/cjs/rendering/caching/RenderingCacheNode.js +4 -3
- package/dist/cjs/rendering/renderers/SVGRenderer.js +8 -19
- package/dist/cjs/rendering/renderers/SVGRenderer.test.d.ts +1 -0
- package/dist/cjs/toolbar/AbstractToolbar.d.ts +11 -3
- package/dist/cjs/toolbar/AbstractToolbar.js +20 -6
- package/dist/cjs/toolbar/EdgeToolbar.js +5 -6
- package/dist/cjs/toolbar/IconProvider.d.ts +1 -0
- package/dist/cjs/toolbar/IconProvider.js +43 -0
- package/dist/cjs/toolbar/widgets/ActionButtonWidget.d.ts +3 -1
- package/dist/cjs/toolbar/widgets/ActionButtonWidget.js +19 -1
- package/dist/cjs/toolbar/widgets/BaseToolWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/BaseToolWidget.js +3 -0
- package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +5 -0
- package/dist/cjs/toolbar/widgets/BaseWidget.js +30 -2
- package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +1 -1
- package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/HandToolWidget.js +6 -0
- package/dist/cjs/toolbar/widgets/InsertImageWidget.js +1 -1
- package/dist/cjs/toolbar/widgets/OverflowWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/OverflowWidget.js +3 -0
- package/dist/cjs/toolbar/widgets/SaveActionWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/SaveActionWidget.js +3 -0
- package/dist/cjs/tools/BaseTool.d.ts +3 -0
- package/dist/cjs/tools/BaseTool.js +13 -2
- package/dist/cjs/tools/FindTool.d.ts +1 -0
- package/dist/cjs/tools/FindTool.js +4 -1
- package/dist/cjs/tools/PanZoom.d.ts +1 -0
- package/dist/cjs/tools/PanZoom.js +4 -0
- package/dist/cjs/tools/Pen.d.ts +0 -1
- package/dist/cjs/tools/Pen.js +1 -4
- package/dist/cjs/tools/PipetteTool.d.ts +1 -0
- package/dist/cjs/tools/PipetteTool.js +3 -0
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -0
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +3 -0
- package/dist/cjs/tools/SelectionTool/Selection.d.ts +2 -0
- package/dist/cjs/tools/SelectionTool/Selection.js +44 -8
- package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +14 -6
- package/dist/cjs/tools/SelectionTool/SelectionHandle.js +26 -8
- package/dist/cjs/tools/SelectionTool/SelectionTool.js +5 -0
- package/dist/cjs/tools/SoundUITool.d.ts +1 -0
- package/dist/cjs/tools/SoundUITool.js +4 -1
- package/dist/cjs/tools/TextTool.js +2 -2
- package/dist/cjs/tools/ToolController.d.ts +2 -0
- package/dist/cjs/tools/ToolController.js +13 -2
- package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +1 -0
- package/dist/cjs/tools/ToolSwitcherShortcut.js +3 -0
- package/dist/cjs/types.d.ts +9 -4
- package/dist/cjs/types.js +4 -3
- package/dist/cjs/util/ReactiveValue.d.ts +1 -1
- package/dist/cjs/util/ReactiveValue.js +2 -2
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.d.ts +36 -3
- package/dist/mjs/Editor.mjs +64 -27
- package/dist/mjs/Editor.toSVGAsync.test.d.ts +1 -0
- package/dist/mjs/SVGLoader.mjs +37 -22
- package/dist/mjs/commands/Erase.mjs +1 -1
- package/dist/mjs/commands/UnresolvedCommand.d.ts +1 -1
- package/dist/mjs/components/AbstractComponent.d.ts +1 -1
- package/dist/mjs/components/AbstractComponent.mjs +1 -1
- package/dist/mjs/components/BackgroundComponent.d.ts +1 -1
- package/dist/mjs/components/BackgroundComponent.mjs +3 -2
- package/dist/mjs/{EditorImage.d.ts → image/EditorImage.d.ts} +30 -8
- package/dist/mjs/{EditorImage.mjs → image/EditorImage.mjs} +51 -7
- package/dist/mjs/image/EditorImage.test.d.ts +1 -0
- package/dist/mjs/image/export/editorImageToSVG.d.ts +8 -0
- package/dist/mjs/image/export/editorImageToSVG.mjs +41 -0
- package/dist/mjs/image/export/setExportedSVGSize.d.ts +6 -0
- package/dist/mjs/image/export/setExportedSVGSize.mjs +23 -0
- package/dist/mjs/image/lib.d.ts +1 -0
- package/dist/mjs/image/lib.mjs +1 -0
- package/dist/mjs/lib.d.ts +1 -1
- package/dist/mjs/lib.mjs +1 -1
- package/dist/mjs/localizations/comments.d.ts +6 -0
- package/dist/mjs/localizations/comments.mjs +8 -0
- package/dist/mjs/localizations/es.mjs +68 -48
- package/dist/mjs/rendering/caching/RenderingCache.d.ts +1 -1
- package/dist/mjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
- package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +4 -3
- package/dist/mjs/rendering/renderers/SVGRenderer.mjs +8 -19
- package/dist/mjs/rendering/renderers/SVGRenderer.test.d.ts +1 -0
- package/dist/mjs/toolbar/AbstractToolbar.d.ts +11 -3
- package/dist/mjs/toolbar/AbstractToolbar.mjs +20 -6
- package/dist/mjs/toolbar/EdgeToolbar.mjs +5 -6
- package/dist/mjs/toolbar/IconProvider.d.ts +1 -0
- package/dist/mjs/toolbar/IconProvider.mjs +43 -0
- package/dist/mjs/toolbar/widgets/ActionButtonWidget.d.ts +3 -1
- package/dist/mjs/toolbar/widgets/ActionButtonWidget.mjs +21 -2
- package/dist/mjs/toolbar/widgets/BaseToolWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +3 -0
- package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +5 -0
- package/dist/mjs/toolbar/widgets/BaseWidget.mjs +30 -2
- package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +1 -1
- package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +6 -0
- package/dist/mjs/toolbar/widgets/InsertImageWidget.mjs +1 -1
- package/dist/mjs/toolbar/widgets/OverflowWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/OverflowWidget.mjs +3 -0
- package/dist/mjs/toolbar/widgets/SaveActionWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/SaveActionWidget.mjs +3 -0
- package/dist/mjs/tools/BaseTool.d.ts +3 -0
- package/dist/mjs/tools/BaseTool.mjs +13 -2
- package/dist/mjs/tools/FindTool.d.ts +1 -0
- package/dist/mjs/tools/FindTool.mjs +4 -1
- package/dist/mjs/tools/PanZoom.d.ts +1 -0
- package/dist/mjs/tools/PanZoom.mjs +4 -0
- package/dist/mjs/tools/Pen.d.ts +0 -1
- package/dist/mjs/tools/Pen.mjs +1 -4
- package/dist/mjs/tools/PipetteTool.d.ts +1 -0
- package/dist/mjs/tools/PipetteTool.mjs +3 -0
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -0
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +3 -0
- package/dist/mjs/tools/SelectionTool/Selection.d.ts +2 -0
- package/dist/mjs/tools/SelectionTool/Selection.mjs +45 -9
- package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +14 -6
- package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +25 -7
- package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +5 -0
- package/dist/mjs/tools/SoundUITool.d.ts +1 -0
- package/dist/mjs/tools/SoundUITool.mjs +4 -1
- package/dist/mjs/tools/TextTool.mjs +2 -2
- package/dist/mjs/tools/ToolController.d.ts +2 -0
- package/dist/mjs/tools/ToolController.mjs +13 -2
- package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +1 -0
- package/dist/mjs/tools/ToolSwitcherShortcut.mjs +3 -0
- package/dist/mjs/types.d.ts +9 -4
- package/dist/mjs/types.mjs +4 -3
- package/dist/mjs/util/ReactiveValue.d.ts +1 -1
- package/dist/mjs/util/ReactiveValue.mjs +2 -2
- package/dist/mjs/version.mjs +1 -1
- package/package.json +5 -5
- package/src/Editor.scss +6 -0
- package/src/toolbar/EdgeToolbar.scss +19 -2
- package/src/tools/SelectionTool/SelectionTool.scss +74 -0
- package/src/tools/tools.scss +1 -1
- package/src/tools/SelectionTool/SelectionTool.css +0 -35
- /package/dist/cjs/{EditorImage.test.d.ts → Editor.toSVGAsync.test.d.ts} +0 -0
- /package/dist/{mjs → cjs/image}/EditorImage.test.d.ts +0 -0
@@ -1,11 +1,11 @@
|
|
1
|
-
import AbstractRenderer from '
|
2
|
-
import Viewport from '
|
3
|
-
import AbstractComponent from '
|
1
|
+
import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
|
2
|
+
import Viewport from '../Viewport';
|
3
|
+
import AbstractComponent from '../components/AbstractComponent';
|
4
4
|
import { Rect2 } from '@js-draw/math';
|
5
|
-
import RenderingCache from '
|
6
|
-
import SerializableCommand from '
|
7
|
-
import EventDispatcher from '
|
8
|
-
import Command from '
|
5
|
+
import RenderingCache from '../rendering/caching/RenderingCache';
|
6
|
+
import SerializableCommand from '../commands/SerializableCommand';
|
7
|
+
import EventDispatcher from '../EventDispatcher';
|
8
|
+
import Command from '../commands/Command';
|
9
9
|
export declare const sortLeavesByZIndex: (leaves: Array<ImageNode>) => void;
|
10
10
|
export declare enum EditorImageEventType {
|
11
11
|
ExportViewportChanged = 0,
|
@@ -14,6 +14,13 @@ export declare enum EditorImageEventType {
|
|
14
14
|
export type EditorImageNotifier = EventDispatcher<EditorImageEventType, {
|
15
15
|
image: EditorImage;
|
16
16
|
}>;
|
17
|
+
/**
|
18
|
+
* A callback used to
|
19
|
+
* 1. pause the render process
|
20
|
+
* 2. observe progress through `componentsProcessed` and `totalComponents`
|
21
|
+
* 3. stop the render process early by returning `false`.
|
22
|
+
*/
|
23
|
+
export type PreRenderComponentCallback = (component: AbstractComponent, componentsProcessed: number, totalComponents: number) => Promise<boolean>;
|
17
24
|
export default class EditorImage {
|
18
25
|
private root;
|
19
26
|
private background;
|
@@ -36,7 +43,21 @@ export default class EditorImage {
|
|
36
43
|
* the viewport used by the `renderer` (if any).
|
37
44
|
*/
|
38
45
|
render(renderer: AbstractRenderer, viewport: Viewport | null): void;
|
39
|
-
/**
|
46
|
+
/**
|
47
|
+
* Like {@link renderAll}, but can be stopped early and paused.
|
48
|
+
*
|
49
|
+
* **Note**: If the image is being edited during an async rendering, there is no
|
50
|
+
* guarantee that all nodes will be rendered correctly (some may be missing).
|
51
|
+
*
|
52
|
+
* @internal
|
53
|
+
*/
|
54
|
+
renderAllAsync(renderer: AbstractRenderer, preRenderComponent: PreRenderComponentCallback): Promise<boolean>;
|
55
|
+
/**
|
56
|
+
* Renders all nodes, even ones not within the viewport.
|
57
|
+
*
|
58
|
+
* This can be slow for large images
|
59
|
+
* @internal
|
60
|
+
*/
|
40
61
|
renderAll(renderer: AbstractRenderer): void;
|
41
62
|
/**
|
42
63
|
* @returns all elements in the image, sorted by z-index. This can be slow for large images.
|
@@ -136,6 +157,7 @@ export declare class ImageNode {
|
|
136
157
|
private rebalance;
|
137
158
|
protected removeChild(child: ImageNode): void;
|
138
159
|
remove(): void;
|
160
|
+
renderAllAsync(renderer: AbstractRenderer, preRenderComponent: PreRenderComponentCallback): Promise<boolean>;
|
139
161
|
render(renderer: AbstractRenderer, visibleRect?: Rect2): void;
|
140
162
|
renderDebugBoundingBoxes(renderer: AbstractRenderer, visibleRect: Rect2, depth?: number): void;
|
141
163
|
}
|
@@ -32,13 +32,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
32
32
|
var _a, _b, _c;
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
34
34
|
exports.RootImageNode = exports.ImageNode = exports.EditorImageEventType = exports.sortLeavesByZIndex = void 0;
|
35
|
-
const Viewport_1 = __importDefault(require("
|
36
|
-
const AbstractComponent_1 = __importStar(require("
|
35
|
+
const Viewport_1 = __importDefault(require("../Viewport"));
|
36
|
+
const AbstractComponent_1 = __importStar(require("../components/AbstractComponent"));
|
37
37
|
const math_1 = require("@js-draw/math");
|
38
|
-
const SerializableCommand_1 = __importDefault(require("
|
39
|
-
const EventDispatcher_1 = __importDefault(require("
|
40
|
-
const assertions_1 = require("
|
41
|
-
const Command_1 = __importDefault(require("
|
38
|
+
const SerializableCommand_1 = __importDefault(require("../commands/SerializableCommand"));
|
39
|
+
const EventDispatcher_1 = __importDefault(require("../EventDispatcher"));
|
40
|
+
const assertions_1 = require("../util/assertions");
|
41
|
+
const Command_1 = __importDefault(require("../commands/Command"));
|
42
42
|
// @internal Sort by z-index, low to high
|
43
43
|
const sortLeavesByZIndex = (leaves) => {
|
44
44
|
leaves.sort((a, b) => a.getContent().getZIndex() - b.getContent().getZIndex());
|
@@ -117,7 +117,27 @@ class EditorImage {
|
|
117
117
|
this.background.render(renderer, viewport?.visibleRect);
|
118
118
|
this.root.render(renderer, viewport?.visibleRect);
|
119
119
|
}
|
120
|
-
/**
|
120
|
+
/**
|
121
|
+
* Like {@link renderAll}, but can be stopped early and paused.
|
122
|
+
*
|
123
|
+
* **Note**: If the image is being edited during an async rendering, there is no
|
124
|
+
* guarantee that all nodes will be rendered correctly (some may be missing).
|
125
|
+
*
|
126
|
+
* @internal
|
127
|
+
*/
|
128
|
+
async renderAllAsync(renderer, preRenderComponent) {
|
129
|
+
const stoppedEarly = !(await this.background.renderAllAsync(renderer, preRenderComponent));
|
130
|
+
if (!stoppedEarly) {
|
131
|
+
return await this.root.renderAllAsync(renderer, preRenderComponent);
|
132
|
+
}
|
133
|
+
return false;
|
134
|
+
}
|
135
|
+
/**
|
136
|
+
* Renders all nodes, even ones not within the viewport.
|
137
|
+
*
|
138
|
+
* This can be slow for large images
|
139
|
+
* @internal
|
140
|
+
*/
|
121
141
|
renderAll(renderer) {
|
122
142
|
this.render(renderer, null);
|
123
143
|
}
|
@@ -640,6 +660,30 @@ class ImageNode {
|
|
640
660
|
this.content = null;
|
641
661
|
this.children = [];
|
642
662
|
}
|
663
|
+
// Creates a (potentially incomplete) async rendering of this image.
|
664
|
+
// Returns false if stopped early
|
665
|
+
async renderAllAsync(renderer,
|
666
|
+
// Used to pause/stop the renderer process
|
667
|
+
preRenderComponent) {
|
668
|
+
const leaves = this.getLeaves();
|
669
|
+
(0, exports.sortLeavesByZIndex)(leaves);
|
670
|
+
const totalLeaves = leaves.length;
|
671
|
+
for (let leafIndex = 0; leafIndex < totalLeaves; leafIndex++) {
|
672
|
+
const leaf = leaves[leafIndex];
|
673
|
+
const component = leaf.getContent();
|
674
|
+
// Even though leaf was originally a leaf, it might not be any longer --
|
675
|
+
// rendering is async and the tree can change during that time.
|
676
|
+
if (!component) {
|
677
|
+
continue;
|
678
|
+
}
|
679
|
+
const shouldContinue = await preRenderComponent(component, leafIndex, totalLeaves);
|
680
|
+
if (!shouldContinue) {
|
681
|
+
return false;
|
682
|
+
}
|
683
|
+
component.render(renderer, undefined);
|
684
|
+
}
|
685
|
+
return true;
|
686
|
+
}
|
643
687
|
render(renderer, visibleRect) {
|
644
688
|
let leaves;
|
645
689
|
if (visibleRect) {
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import EditorImage, { PreRenderComponentCallback } from '../EditorImage';
|
2
|
+
import { SVGSizingOptions } from './setExportedSVGSize';
|
3
|
+
export interface SVGExportOptions extends SVGSizingOptions {
|
4
|
+
sanitize?: boolean;
|
5
|
+
minDimension?: number;
|
6
|
+
}
|
7
|
+
export declare const editorImageToSVGSync: (image: EditorImage, options: SVGExportOptions) => SVGSVGElement;
|
8
|
+
export declare const editorImageToSVGAsync: (image: EditorImage, preRenderComponent: PreRenderComponentCallback, options: SVGExportOptions) => Promise<SVGElement>;
|
@@ -0,0 +1,49 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.editorImageToSVGAsync = exports.editorImageToSVGSync = void 0;
|
7
|
+
const math_1 = require("@js-draw/math");
|
8
|
+
const SVGRenderer_1 = __importDefault(require("../../rendering/renderers/SVGRenderer"));
|
9
|
+
const SVGLoader_1 = require("../../SVGLoader");
|
10
|
+
const setExportedSVGSize_1 = __importDefault(require("./setExportedSVGSize"));
|
11
|
+
const toSVGInternal = (image, renderFunction, options) => {
|
12
|
+
const importExportViewport = image.getImportExportViewport().getTemporaryClone();
|
13
|
+
const { element: result, renderer } = SVGRenderer_1.default.fromViewport(importExportViewport, options.sanitize ?? false);
|
14
|
+
const origTransform = importExportViewport.canvasToScreenTransform;
|
15
|
+
// Render with (0,0) at (0,0) — we'll handle translation with
|
16
|
+
// the viewBox property.
|
17
|
+
importExportViewport.resetTransform(math_1.Mat33.identity);
|
18
|
+
// Use a callback rather than async/await to allow this function to create
|
19
|
+
// both sync and async render functions
|
20
|
+
renderFunction(renderer, () => {
|
21
|
+
importExportViewport.resetTransform(origTransform);
|
22
|
+
if (image.getAutoresizeEnabled()) {
|
23
|
+
result.classList.add(SVGLoader_1.svgLoaderAutoresizeClassName);
|
24
|
+
}
|
25
|
+
else {
|
26
|
+
result.classList.remove(SVGLoader_1.svgLoaderAutoresizeClassName);
|
27
|
+
}
|
28
|
+
(0, setExportedSVGSize_1.default)(result, importExportViewport, options);
|
29
|
+
return result;
|
30
|
+
});
|
31
|
+
return result;
|
32
|
+
};
|
33
|
+
const editorImageToSVGSync = (image, options) => {
|
34
|
+
return toSVGInternal(image, (renderer, onComplete) => {
|
35
|
+
image.renderAll(renderer);
|
36
|
+
onComplete();
|
37
|
+
}, options);
|
38
|
+
};
|
39
|
+
exports.editorImageToSVGSync = editorImageToSVGSync;
|
40
|
+
const editorImageToSVGAsync = (image, preRenderComponent, options) => {
|
41
|
+
return new Promise(resolve => {
|
42
|
+
toSVGInternal(image, async (renderer, onComplete) => {
|
43
|
+
await image.renderAllAsync(renderer, preRenderComponent);
|
44
|
+
const result = onComplete();
|
45
|
+
resolve(result);
|
46
|
+
}, options);
|
47
|
+
});
|
48
|
+
};
|
49
|
+
exports.editorImageToSVGAsync = editorImageToSVGAsync;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const math_1 = require("@js-draw/math");
|
4
|
+
// @internal
|
5
|
+
const setExportedSVGSize = (svg, viewport, options) => {
|
6
|
+
// Just show the main region
|
7
|
+
const rect = viewport.visibleRect;
|
8
|
+
svg.setAttribute('viewBox', [rect.x, rect.y, rect.w, rect.h].map(part => (0, math_1.toRoundedString)(part)).join(' '));
|
9
|
+
// Adjust the width/height as necessary
|
10
|
+
let width = rect.w;
|
11
|
+
let height = rect.h;
|
12
|
+
if (options?.minDimension && width < options.minDimension) {
|
13
|
+
const newWidth = options.minDimension;
|
14
|
+
height *= newWidth / (width || 1);
|
15
|
+
width = newWidth;
|
16
|
+
}
|
17
|
+
if (options?.minDimension && height < options.minDimension) {
|
18
|
+
const newHeight = options.minDimension;
|
19
|
+
width *= newHeight / (height || 1);
|
20
|
+
height = newHeight;
|
21
|
+
}
|
22
|
+
svg.setAttribute('width', (0, math_1.toRoundedString)(width));
|
23
|
+
svg.setAttribute('height', (0, math_1.toRoundedString)(height));
|
24
|
+
};
|
25
|
+
exports.default = setExportedSVGSize;
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default as EditorImage } from './EditorImage';
|
@@ -0,0 +1,8 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.EditorImage = void 0;
|
7
|
+
var EditorImage_1 = require("./EditorImage");
|
8
|
+
Object.defineProperty(exports, "EditorImage", { enumerable: true, get: function () { return __importDefault(EditorImage_1).default; } });
|
package/dist/cjs/lib.d.ts
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
* @packageDocumentation
|
16
16
|
*/
|
17
17
|
import Editor, { EditorSettings } from './Editor';
|
18
|
-
export
|
18
|
+
export * from './image/lib';
|
19
19
|
export * from './types';
|
20
20
|
export * from './inputEvents';
|
21
21
|
export { default as getLocalizationTable, matchingLocalizationTable } from './localizations/getLocalizationTable';
|
package/dist/cjs/lib.js
CHANGED
@@ -33,11 +33,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33
33
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
34
34
|
};
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
36
|
-
exports.HTMLToolbar = exports.AbstractToolbar = exports.Editor = exports.__js_draw__version = exports.UndoRedoHistory = exports.PointerDevice = exports.Pointer = exports.EventDispatcher = exports.Viewport = exports.SVGLoader = exports.matchingLocalizationTable = exports.getLocalizationTable =
|
36
|
+
exports.HTMLToolbar = exports.AbstractToolbar = exports.Editor = exports.__js_draw__version = exports.UndoRedoHistory = exports.PointerDevice = exports.Pointer = exports.EventDispatcher = exports.Viewport = exports.SVGLoader = exports.matchingLocalizationTable = exports.getLocalizationTable = void 0;
|
37
37
|
const Editor_1 = __importDefault(require("./Editor"));
|
38
38
|
exports.Editor = Editor_1.default;
|
39
|
-
|
40
|
-
Object.defineProperty(exports, "EditorImage", { enumerable: true, get: function () { return __importDefault(EditorImage_1).default; } });
|
39
|
+
__exportStar(require("./image/lib"), exports);
|
41
40
|
__exportStar(require("./types"), exports);
|
42
41
|
__exportStar(require("./inputEvents"), exports);
|
43
42
|
var getLocalizationTable_1 = require("./localizations/getLocalizationTable");
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
/**
|
4
|
+
* Comments to help translators create translations.
|
5
|
+
*/
|
6
|
+
const comments = {
|
7
|
+
dragAndDropHereOrBrowse: 'Uses {{curly braces}} to denote bold text',
|
8
|
+
closeSidebar: 'Currently used as an accessibilty label',
|
9
|
+
};
|
10
|
+
exports.default = comments;
|
@@ -1,70 +1,90 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
const localization_1 = require("../localization");
|
4
|
-
// A partial Spanish localization.
|
4
|
+
// A partial Spanish localization, created with /scripts/markdownTranslationFormToTs.ts
|
5
5
|
const localization = {
|
6
6
|
...localization_1.defaultEditorLocalization,
|
7
|
-
// Strings for the main editor interface
|
8
|
-
// (see src/localization.ts)
|
9
|
-
loading: (percentage) => `Cargando: ${percentage}%...`,
|
10
|
-
imageEditor: 'Editor de dibujos',
|
11
|
-
undoAnnouncement: (commandDescription) => `${commandDescription} fue deshecho`,
|
12
|
-
redoAnnouncement: (commandDescription) => `${commandDescription} fue rehecho`,
|
13
|
-
undo: 'Deshace',
|
14
|
-
redo: 'Rehace',
|
15
|
-
// Strings for the toolbar
|
16
|
-
// (see src/toolbar/localization.ts)
|
17
7
|
pen: 'Lapiz',
|
18
8
|
eraser: 'Borrador',
|
19
9
|
select: 'Selecciona',
|
20
|
-
thicknessLabel: 'Tamaño',
|
21
|
-
colorLabel: 'Color',
|
22
|
-
doneLoading: 'El cargado terminó',
|
23
|
-
fontLabel: 'Fuente: ',
|
24
|
-
anyDevicePanning: 'Mover la pantalla con todo dispotivo',
|
25
|
-
touchPanning: 'Mover la pantalla con un dedo',
|
26
|
-
touchPanTool: 'Instrumento de mover la pantalla con un dedo',
|
27
|
-
outlinedRectanglePen: 'Rectángulo con nada más que un borde',
|
28
|
-
filledRectanglePen: 'Rectángulo sin borde',
|
29
|
-
linePen: 'Línea',
|
30
|
-
arrowPen: 'Flecha',
|
31
|
-
roundedTipPen: 'Lapiz Redondeado',
|
32
|
-
selectPenTip: 'Forma de dibuja',
|
33
10
|
handTool: 'Mover',
|
34
|
-
|
11
|
+
image: 'Imagen',
|
12
|
+
chooseFile: 'Seleccionar archivo',
|
13
|
+
cancel: 'Cancelar',
|
35
14
|
resetView: 'Reiniciar vista',
|
15
|
+
thicknessLabel: 'Tamaño',
|
16
|
+
fontLabel: 'Fuente:',
|
17
|
+
textSize: 'Tamaño',
|
36
18
|
resizeImageToSelection: 'Redimensionar la imagen a lo que está seleccionado',
|
37
19
|
deleteSelection: 'Borra la selección',
|
38
20
|
duplicateSelection: 'Duplica la selección',
|
21
|
+
exit: 'Salir',
|
22
|
+
save: 'Guardar',
|
23
|
+
undo: 'Deshace',
|
24
|
+
redo: 'Rehace',
|
25
|
+
selectPenTip: 'Punta',
|
26
|
+
selectShape: 'Forma',
|
39
27
|
pickColorFromScreen: 'Selecciona un color de la pantalla',
|
40
28
|
clickToPickColorAnnouncement: 'Haga un clic en la pantalla para seleccionar un color',
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
29
|
+
documentProperties: 'Fondo',
|
30
|
+
backgroundColor: 'Color de fondo',
|
31
|
+
imageWidthOption: 'Ancho',
|
32
|
+
imageHeightOption: 'Alto',
|
33
|
+
toggleOverflow: 'Más',
|
34
|
+
touchPanning: 'Mover la pantalla con un dedo',
|
35
|
+
roundedTipPen: 'Lapiz Redondeado',
|
36
|
+
arrowPen: 'Flecha',
|
37
|
+
linePen: 'Línea',
|
38
|
+
outlinedRectanglePen: 'Rectángulo delineado',
|
39
|
+
filledRectanglePen: 'Rectángulo sin borde',
|
40
|
+
lockRotation: 'Bloquea rotación',
|
41
|
+
paste: 'Pegar',
|
42
|
+
closeSidebar: (toolName) => `Close sidebar for ${toolName}`,
|
43
|
+
dropdownShown: (toolName) => `Menú por ${toolName} es visible`,
|
44
|
+
dropdownHidden: (toolName) => { return `Menú por ${toolName} fue ocultado`; },
|
45
|
+
zoomLevel: (zoomPercent) => `Zoom: ${zoomPercent}%`,
|
46
|
+
colorChangedAnnouncement: (color) => { return `Color fue cambiado a ${color}`; },
|
47
|
+
imageSize: (size, units) => `Tamaño del imagen: ${size} ${units}`,
|
48
|
+
imageLoadError: (message) => `Error cargando imagen: ${message}`,
|
49
|
+
penTool: (penId) => { return `Lapiz ${penId}`; },
|
54
50
|
selectionTool: 'Selecciona',
|
55
51
|
eraserTool: 'Borrador',
|
52
|
+
touchPanTool: 'Instrumento de mover la pantalla con un dedo',
|
53
|
+
pipetteTool: 'Seleccione un color de la pantalla',
|
54
|
+
keyboardPanZoom: 'Mover la pantalla con el teclado',
|
56
55
|
textTool: 'Texto',
|
57
56
|
enterTextToInsert: 'Entra texto',
|
58
|
-
|
57
|
+
findLabel: 'Buscar',
|
58
|
+
toNextMatch: 'Próxima',
|
59
|
+
closeDialog: 'Cerrar',
|
60
|
+
focusedFoundText: (matchIdx, totalMatches) => `Viewing match ${matchIdx} of ${totalMatches}`,
|
61
|
+
anyDevicePanning: 'Mover la pantalla con todo dispotivo',
|
62
|
+
copied: (count, description) => `Copied ${count} ${description}`,
|
63
|
+
pasted: (count, description) => `Pasted ${count} ${description}`,
|
64
|
+
toolEnabledAnnouncement: (toolName) => `${toolName} enabled`,
|
65
|
+
toolDisabledAnnouncement: (toolName) => `${toolName} disabled`,
|
66
|
+
transformedElements: (elemCount) => `Transformed ${elemCount} element${elemCount === 1 ? '' : 's'}`,
|
67
|
+
resizeOutputCommand: (newSize) => `Resized image to ${newSize.w}x${newSize.h}`,
|
68
|
+
addElementAction: (componentDescription) => `Added ${componentDescription}`,
|
69
|
+
eraseAction: (componentDescription, numElems) => `Erased ${numElems} ${componentDescription}`,
|
70
|
+
duplicateAction: (componentDescription, numElems) => `Duplicated ${numElems} ${componentDescription}`,
|
71
|
+
unionOf: (actionDescription, actionCount) => `Union: ${actionCount} ${actionDescription}`,
|
72
|
+
inverseOf: (actionDescription) => `Inverse of ${actionDescription}`,
|
73
|
+
rotatedBy: (degrees) => `Rotated by ${Math.abs(degrees)} degrees ${degrees < 0 ? 'clockwise' : 'counter-clockwise'}`,
|
74
|
+
selectedElements: (count) => `Selected ${count} element${count === 1 ? '' : 's'}`,
|
75
|
+
filledBackgroundWithColor: (color) => `Filled background (${color})`,
|
76
|
+
text: (text) => `Text object: ${text}`,
|
77
|
+
imageNode: (label) => `Image: ${label}`,
|
78
|
+
restyledElement: (elementDescription) => `Restyled ${elementDescription}`,
|
79
|
+
pathNodeCount: (count) => `There are ${count} visible path objects.`,
|
80
|
+
textNodeCount: (count) => `There are ${count} visible text nodes.`,
|
81
|
+
imageNodeCount: (nodeCount) => `There are ${nodeCount} visible image nodes.`,
|
82
|
+
textNode: (content) => `Text: ${content}`,
|
59
83
|
rerenderAsText: 'Redibuja la pantalla al texto',
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
documentProperties: 'Fondo',
|
66
|
-
imageWidthOption: 'Ancho',
|
67
|
-
imageHeightOption: 'Alto',
|
68
|
-
backgroundColor: 'Color de fondo: '
|
84
|
+
loading: (percentage) => `Cargando: ${percentage}%...`,
|
85
|
+
imageEditor: 'Editor de dibujos',
|
86
|
+
doneLoading: 'El cargado terminó',
|
87
|
+
undoAnnouncement: (commandDescription) => `${commandDescription} fue deshecho`,
|
88
|
+
redoAnnouncement: (commandDescription) => `${commandDescription} fue rehecho`,
|
69
89
|
};
|
70
90
|
exports.default = localization;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
// A cache record with sub-nodes.
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
4
|
-
const EditorImage_1 = require("../../EditorImage");
|
4
|
+
const EditorImage_1 = require("../../image/EditorImage");
|
5
5
|
const math_1 = require("@js-draw/math");
|
6
6
|
// 3x3 divisions for each node.
|
7
7
|
const cacheDivisionSize = 3;
|
@@ -44,11 +44,12 @@ class RenderingCacheNode {
|
|
44
44
|
// Generates children, if missing.
|
45
45
|
generateChildren() {
|
46
46
|
if (this.instantiatedChildren.length === 0) {
|
47
|
-
|
48
|
-
if (this.region.size.x === 0 || this.region.size.y === 0) {
|
47
|
+
if (this.region.size.x / cacheDivisionSize === 0 || this.region.size.y / cacheDivisionSize === 0) {
|
49
48
|
console.warn('Cache element has zero size! Not generating children.');
|
50
49
|
return;
|
51
50
|
}
|
51
|
+
const childRects = this.region.divideIntoGrid(cacheDivisionSize, cacheDivisionSize);
|
52
|
+
console.assert(childRects.length === cacheDivisionSize * cacheDivisionSize, 'Warning: divideIntoGrid created the wrong number of subrectangles!');
|
52
53
|
for (const rect of childRects) {
|
53
54
|
const child = new RenderingCacheNode(rect, this.cacheState);
|
54
55
|
child.parent = this;
|
@@ -135,26 +135,18 @@ class SVGRenderer extends AbstractRenderer_1.default {
|
|
135
135
|
}
|
136
136
|
// Apply [elemTransform] to [elem]. Uses both a `matrix` and `.x`, `.y` properties if `setXY` is true.
|
137
137
|
// Otherwise, just uses a `matrix`.
|
138
|
-
transformFrom(elemTransform, elem, inCanvasSpace = false
|
139
|
-
|
140
|
-
const translation = transform.transformVec2(math_1.Vec2.zero);
|
141
|
-
if (setXY) {
|
142
|
-
transform = transform.rightMul(math_1.Mat33.translation(translation.times(-1)));
|
143
|
-
}
|
138
|
+
transformFrom(elemTransform, elem, inCanvasSpace = false) {
|
139
|
+
const transform = !inCanvasSpace ? this.getCanvasToScreenTransform().rightMul(elemTransform) : elemTransform;
|
144
140
|
if (!transform.eq(math_1.Mat33.identity)) {
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
141
|
+
const matrixString = transform.toCSSMatrix();
|
142
|
+
elem.style.transform = matrixString;
|
143
|
+
// Most browsers round the components of CSS transforms.
|
144
|
+
// Include a higher precision copy of the element's transform.
|
145
|
+
elem.setAttribute('data-highp-transform', matrixString);
|
150
146
|
}
|
151
147
|
else {
|
152
148
|
elem.style.transform = '';
|
153
149
|
}
|
154
|
-
if (setXY) {
|
155
|
-
elem.setAttribute('x', `${(0, math_1.toRoundedString)(translation.x)}`);
|
156
|
-
elem.setAttribute('y', `${(0, math_1.toRoundedString)(translation.y)}`);
|
157
|
-
}
|
158
150
|
}
|
159
151
|
drawText(text, transform, style) {
|
160
152
|
const applyTextStyles = (elem, style) => {
|
@@ -190,10 +182,7 @@ class SVGRenderer extends AbstractRenderer_1.default {
|
|
190
182
|
if (!this.textContainer) {
|
191
183
|
const container = document.createElementNS(svgNameSpace, 'text');
|
192
184
|
container.appendChild(document.createTextNode(text));
|
193
|
-
|
194
|
-
// Child nodes aren't translated by .x/.y properties, but are by .style.transform.
|
195
|
-
const setXY = false;
|
196
|
-
this.transformFrom(transform, container, true, setXY);
|
185
|
+
this.transformFrom(transform, container, true);
|
197
186
|
applyTextStyles(container, style);
|
198
187
|
this.elem.appendChild(container);
|
199
188
|
this.objectElems?.push(container);
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -8,6 +8,10 @@ export interface SpacerOptions {
|
|
8
8
|
minSize: string;
|
9
9
|
maxSize: string;
|
10
10
|
}
|
11
|
+
export type ToolbarActionButtonOptions = {
|
12
|
+
mustBeToplevel?: boolean;
|
13
|
+
autoDisableInReadOnlyEditors?: boolean;
|
14
|
+
};
|
11
15
|
export default abstract class AbstractToolbar {
|
12
16
|
#private;
|
13
17
|
protected editor: Editor;
|
@@ -91,18 +95,22 @@ export default abstract class AbstractToolbar {
|
|
91
95
|
* @see
|
92
96
|
* {@link addActionButton}
|
93
97
|
*/
|
94
|
-
protected makeActionButton(title: string | ActionButtonIcon, command: () => void,
|
98
|
+
protected makeActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
|
95
99
|
/**
|
96
100
|
* Adds an action button with `title` to this toolbar (or to the given `parent` element).
|
97
101
|
*
|
102
|
+
* `options` can either be an object with properties `mustBeToplevel` and/or
|
103
|
+
* `autoDisableInReadOnlyEditors` or a boolean value. If a boolean, it is interpreted
|
104
|
+
* as being the value of `mustBeToplevel`.
|
105
|
+
*
|
98
106
|
* @return The added button.
|
99
107
|
*/
|
100
|
-
addActionButton(title: string | ActionButtonIcon, command: () => void,
|
108
|
+
addActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
|
101
109
|
/**
|
102
110
|
* Like {@link addActionButton}, except associates `tags` with the button that allow
|
103
111
|
* different toolbar styles to give the button tag-dependent styles.
|
104
112
|
*/
|
105
|
-
addTaggedActionButton(tags: (ToolbarWidgetTag | string)[], title: string | ActionButtonIcon, command: () => void,
|
113
|
+
addTaggedActionButton(tags: (ToolbarWidgetTag | string)[], title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
|
106
114
|
/**
|
107
115
|
* Adds a save button that, when clicked, calls `saveCallback`.
|
108
116
|
*
|
@@ -235,7 +235,15 @@ class AbstractToolbar {
|
|
235
235
|
* @see
|
236
236
|
* {@link addActionButton}
|
237
237
|
*/
|
238
|
-
makeActionButton(title, command,
|
238
|
+
makeActionButton(title, command, options = true) {
|
239
|
+
// Parse options
|
240
|
+
if (typeof options === 'boolean') {
|
241
|
+
options = {
|
242
|
+
mustBeToplevel: options,
|
243
|
+
};
|
244
|
+
}
|
245
|
+
const mustBeToplevel = options.mustBeToplevel ?? true;
|
246
|
+
const autoDisableInReadOnlyEditors = options.autoDisableInReadOnlyEditors ?? true;
|
239
247
|
const titleString = typeof title === 'string' ? title : title.label;
|
240
248
|
const widgetId = 'action-button';
|
241
249
|
const makeIcon = () => {
|
@@ -244,16 +252,20 @@ class AbstractToolbar {
|
|
244
252
|
}
|
245
253
|
return title.icon;
|
246
254
|
};
|
247
|
-
const widget = new ActionButtonWidget_1.default(this.editor, widgetId, makeIcon, titleString, command, this.editor.localization, mustBeToplevel);
|
255
|
+
const widget = new ActionButtonWidget_1.default(this.editor, widgetId, makeIcon, titleString, command, this.editor.localization, mustBeToplevel, autoDisableInReadOnlyEditors);
|
248
256
|
return widget;
|
249
257
|
}
|
250
258
|
/**
|
251
259
|
* Adds an action button with `title` to this toolbar (or to the given `parent` element).
|
252
260
|
*
|
261
|
+
* `options` can either be an object with properties `mustBeToplevel` and/or
|
262
|
+
* `autoDisableInReadOnlyEditors` or a boolean value. If a boolean, it is interpreted
|
263
|
+
* as being the value of `mustBeToplevel`.
|
264
|
+
*
|
253
265
|
* @return The added button.
|
254
266
|
*/
|
255
|
-
addActionButton(title, command,
|
256
|
-
const widget = this.makeActionButton(title, command,
|
267
|
+
addActionButton(title, command, options = true) {
|
268
|
+
const widget = this.makeActionButton(title, command, options);
|
257
269
|
this.addWidget(widget);
|
258
270
|
return widget;
|
259
271
|
}
|
@@ -261,8 +273,8 @@ class AbstractToolbar {
|
|
261
273
|
* Like {@link addActionButton}, except associates `tags` with the button that allow
|
262
274
|
* different toolbar styles to give the button tag-dependent styles.
|
263
275
|
*/
|
264
|
-
addTaggedActionButton(tags, title, command,
|
265
|
-
const widget = this.makeActionButton(title, command,
|
276
|
+
addTaggedActionButton(tags, title, command, options = true) {
|
277
|
+
const widget = this.makeActionButton(title, command, options);
|
266
278
|
widget.setTags(tags);
|
267
279
|
this.addWidget(widget);
|
268
280
|
return widget;
|
@@ -308,6 +320,8 @@ class AbstractToolbar {
|
|
308
320
|
icon: this.editor.icons.makeCloseIcon(),
|
309
321
|
}, () => {
|
310
322
|
exitCallback();
|
323
|
+
}, {
|
324
|
+
autoDisableInReadOnlyEditors: false,
|
311
325
|
});
|
312
326
|
}
|
313
327
|
/**
|