js-draw 1.3.1 → 1.4.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.
- package/README.md +2 -2
- 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/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 +13 -7
- package/dist/cjs/components/SVGGlobalAttributesObject.d.ts +2 -2
- package/dist/cjs/components/SVGGlobalAttributesObject.js +10 -14
- 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/adjustExportedSVGSize.d.ts +6 -0
- package/dist/cjs/image/export/adjustExportedSVGSize.js +22 -0
- package/dist/cjs/image/export/editorImageToSVG.d.ts +8 -0
- package/dist/cjs/image/export/editorImageToSVG.js +63 -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/AbstractRenderer.d.ts +1 -0
- package/dist/cjs/rendering/renderers/AbstractRenderer.js +8 -0
- package/dist/cjs/rendering/renderers/SVGRenderer.d.ts +28 -1
- package/dist/cjs/rendering/renderers/SVGRenderer.js +58 -7
- 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/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 +13 -7
- package/dist/mjs/components/SVGGlobalAttributesObject.d.ts +2 -2
- package/dist/mjs/components/SVGGlobalAttributesObject.mjs +10 -14
- 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/adjustExportedSVGSize.d.ts +6 -0
- package/dist/mjs/image/export/adjustExportedSVGSize.mjs +20 -0
- package/dist/mjs/image/export/editorImageToSVG.d.ts +8 -0
- package/dist/mjs/image/export/editorImageToSVG.mjs +55 -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/AbstractRenderer.d.ts +1 -0
- package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +8 -0
- package/dist/mjs/rendering/renderers/SVGRenderer.d.ts +28 -1
- package/dist/mjs/rendering/renderers/SVGRenderer.mjs +58 -7
- 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,22 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const math_1 = require("@js-draw/math");
|
4
|
+
// @internal
|
5
|
+
const adjustExportedSVGSize = (svg, exportRect, options) => {
|
6
|
+
// Adjust the width/height as necessary
|
7
|
+
let width = exportRect.w;
|
8
|
+
let height = exportRect.h;
|
9
|
+
if (options?.minDimension && width < options.minDimension) {
|
10
|
+
const newWidth = options.minDimension;
|
11
|
+
height *= newWidth / (width || 1);
|
12
|
+
width = newWidth;
|
13
|
+
}
|
14
|
+
if (options?.minDimension && height < options.minDimension) {
|
15
|
+
const newHeight = options.minDimension;
|
16
|
+
width *= newHeight / (height || 1);
|
17
|
+
height = newHeight;
|
18
|
+
}
|
19
|
+
svg.setAttribute('width', (0, math_1.toRoundedString)(width));
|
20
|
+
svg.setAttribute('height', (0, math_1.toRoundedString)(height));
|
21
|
+
};
|
22
|
+
exports.default = adjustExportedSVGSize;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import EditorImage, { PreRenderComponentCallback } from '../EditorImage';
|
2
|
+
import { SVGSizingOptions } from './adjustExportedSVGSize';
|
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,63 @@
|
|
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 adjustExportedSVGSize_1 = __importDefault(require("./adjustExportedSVGSize"));
|
11
|
+
const toSVGInternal = (image, renderFunction, options) => {
|
12
|
+
const importExportViewport = image.getImportExportViewport().getTemporaryClone();
|
13
|
+
// If the rectangle has zero width or height, its size can't be increased
|
14
|
+
// -- set its size to the minimum.
|
15
|
+
if (options?.minDimension) {
|
16
|
+
const originalRect = importExportViewport.visibleRect;
|
17
|
+
let rect = originalRect;
|
18
|
+
if (rect.w <= 0) {
|
19
|
+
rect = new math_1.Rect2(rect.x, rect.y, options.minDimension, rect.h);
|
20
|
+
}
|
21
|
+
if (rect.h <= 0) {
|
22
|
+
rect = new math_1.Rect2(rect.x, rect.y, rect.w, options.minDimension);
|
23
|
+
}
|
24
|
+
if (!rect.eq(originalRect)) {
|
25
|
+
importExportViewport.updateScreenSize(rect.size);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
const { element: result, renderer } = SVGRenderer_1.default.fromViewport(importExportViewport, {
|
29
|
+
sanitize: options.sanitize ?? false,
|
30
|
+
useViewBoxForPositioning: true,
|
31
|
+
});
|
32
|
+
// Use a callback rather than async/await to allow this function to create
|
33
|
+
// both sync and async render functions
|
34
|
+
renderFunction(renderer, () => {
|
35
|
+
if (image.getAutoresizeEnabled()) {
|
36
|
+
result.classList.add(SVGLoader_1.svgLoaderAutoresizeClassName);
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
result.classList.remove(SVGLoader_1.svgLoaderAutoresizeClassName);
|
40
|
+
}
|
41
|
+
const exportRect = importExportViewport.visibleRect;
|
42
|
+
(0, adjustExportedSVGSize_1.default)(result, exportRect, options);
|
43
|
+
return result;
|
44
|
+
});
|
45
|
+
return result;
|
46
|
+
};
|
47
|
+
const editorImageToSVGSync = (image, options) => {
|
48
|
+
return toSVGInternal(image, (renderer, onComplete) => {
|
49
|
+
image.renderAll(renderer);
|
50
|
+
onComplete();
|
51
|
+
}, options);
|
52
|
+
};
|
53
|
+
exports.editorImageToSVGSync = editorImageToSVGSync;
|
54
|
+
const editorImageToSVGAsync = (image, preRenderComponent, options) => {
|
55
|
+
return new Promise(resolve => {
|
56
|
+
toSVGInternal(image, async (renderer, onComplete) => {
|
57
|
+
await image.renderAllAsync(renderer, preRenderComponent);
|
58
|
+
const result = onComplete();
|
59
|
+
resolve(result);
|
60
|
+
}, options);
|
61
|
+
});
|
62
|
+
};
|
63
|
+
exports.editorImageToSVGAsync = editorImageToSVGAsync;
|
@@ -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;
|
@@ -160,5 +160,13 @@ class AbstractRenderer {
|
|
160
160
|
getSizeOfCanvasPixelOnScreen() {
|
161
161
|
return this.getCanvasToScreenTransform().transformVec3(math_1.Vec2.unitX).length();
|
162
162
|
}
|
163
|
+
// Returns the region in canvas space that is visible within the viewport this
|
164
|
+
// canvas is rendering to.
|
165
|
+
//
|
166
|
+
// Note that in some cases this might not be the same as the `visibleRect` given
|
167
|
+
// to components in their `render` method.
|
168
|
+
getVisibleRect() {
|
169
|
+
return this.viewport.visibleRect;
|
170
|
+
}
|
163
171
|
}
|
164
172
|
exports.default = AbstractRenderer;
|
@@ -6,6 +6,15 @@ import TextRenderingStyle from '../TextRenderingStyle';
|
|
6
6
|
import AbstractRenderer, { RenderableImage } from './AbstractRenderer';
|
7
7
|
import RenderablePathSpec from '../RenderablePathSpec';
|
8
8
|
export declare const renderedStylesheetId = "js-draw-style-sheet";
|
9
|
+
type FromViewportOptions = {
|
10
|
+
sanitize?: boolean;
|
11
|
+
/**
|
12
|
+
* Rather than having the top left of the `viewBox` set to (0, 0),
|
13
|
+
* if `useViewBoxForPositioning` is `true`, the `viewBox`'s top left
|
14
|
+
* is based on the top left of the rendering viewport's `visibleRect`.
|
15
|
+
*/
|
16
|
+
useViewBoxForPositioning?: boolean;
|
17
|
+
};
|
9
18
|
/**
|
10
19
|
* Renders onto an `SVGElement`.
|
11
20
|
*
|
@@ -50,8 +59,26 @@ export default class SVGRenderer extends AbstractRenderer {
|
|
50
59
|
drawPoints(...points: Point2[]): void;
|
51
60
|
drawSVGElem(elem: SVGElement): void;
|
52
61
|
isTooSmallToRender(_rect: Rect2): boolean;
|
53
|
-
|
62
|
+
private visibleRectOverride;
|
63
|
+
/**
|
64
|
+
* Overrides the visible region returned by `getVisibleRect`.
|
65
|
+
*
|
66
|
+
* This is useful when the `viewport`'s transform has been modified,
|
67
|
+
* for example, to compensate for storing part of the image's
|
68
|
+
* transformation in an SVG property.
|
69
|
+
*/
|
70
|
+
private overrideVisibleRect;
|
71
|
+
getVisibleRect(): Rect2;
|
72
|
+
/**
|
73
|
+
* Creates a new SVG element and `SVGRenerer` with `width`, `height`, `viewBox`,
|
74
|
+
* and other metadata attributes set for the given `Viewport`.
|
75
|
+
*
|
76
|
+
* If `options` is a `boolean`, it is interpreted as whether to sanitize (not add unknown
|
77
|
+
* SVG entities to) the output.
|
78
|
+
*/
|
79
|
+
static fromViewport(viewport: Viewport, options?: FromViewportOptions | boolean): {
|
54
80
|
element: SVGSVGElement;
|
55
81
|
renderer: SVGRenderer;
|
56
82
|
};
|
57
83
|
}
|
84
|
+
export {};
|
@@ -42,6 +42,7 @@ class SVGRenderer extends AbstractRenderer_1.default {
|
|
42
42
|
this.textContainer = null;
|
43
43
|
this.textContainerTransform = null;
|
44
44
|
this.textParentStyle = defaultTextStyle;
|
45
|
+
this.visibleRectOverride = null;
|
45
46
|
this.clear();
|
46
47
|
this.addStyleSheet();
|
47
48
|
}
|
@@ -344,21 +345,71 @@ class SVGRenderer extends AbstractRenderer_1.default {
|
|
344
345
|
isTooSmallToRender(_rect) {
|
345
346
|
return false;
|
346
347
|
}
|
347
|
-
|
348
|
-
|
348
|
+
/**
|
349
|
+
* Overrides the visible region returned by `getVisibleRect`.
|
350
|
+
*
|
351
|
+
* This is useful when the `viewport`'s transform has been modified,
|
352
|
+
* for example, to compensate for storing part of the image's
|
353
|
+
* transformation in an SVG property.
|
354
|
+
*/
|
355
|
+
overrideVisibleRect(newRect) {
|
356
|
+
this.visibleRectOverride = newRect;
|
357
|
+
}
|
358
|
+
getVisibleRect() {
|
359
|
+
return this.visibleRectOverride ?? super.getVisibleRect();
|
360
|
+
}
|
361
|
+
/**
|
362
|
+
* Creates a new SVG element and `SVGRenerer` with `width`, `height`, `viewBox`,
|
363
|
+
* and other metadata attributes set for the given `Viewport`.
|
364
|
+
*
|
365
|
+
* If `options` is a `boolean`, it is interpreted as whether to sanitize (not add unknown
|
366
|
+
* SVG entities to) the output.
|
367
|
+
*/
|
368
|
+
static fromViewport(viewport, options = true) {
|
369
|
+
let sanitize;
|
370
|
+
let useViewBoxForPositioning;
|
371
|
+
if (typeof options === 'boolean') {
|
372
|
+
sanitize = options;
|
373
|
+
useViewBoxForPositioning = false;
|
374
|
+
}
|
375
|
+
else {
|
376
|
+
sanitize = options.sanitize ?? true;
|
377
|
+
useViewBoxForPositioning = options.useViewBoxForPositioning ?? false;
|
378
|
+
}
|
349
379
|
const svgNameSpace = 'http://www.w3.org/2000/svg';
|
350
380
|
const result = document.createElementNS(svgNameSpace, 'svg');
|
351
|
-
const
|
381
|
+
const screenRectSize = viewport.getScreenRectSize();
|
382
|
+
const visibleRect = viewport.visibleRect;
|
383
|
+
let viewBoxComponents;
|
384
|
+
if (useViewBoxForPositioning) {
|
385
|
+
const exportRect = viewport.visibleRect;
|
386
|
+
viewBoxComponents = [
|
387
|
+
exportRect.x, exportRect.y, exportRect.w, exportRect.h,
|
388
|
+
];
|
389
|
+
// Replace the viewport with a copy that has a modified transform.
|
390
|
+
// (Avoids modifying the original viewport).
|
391
|
+
viewport = viewport.getTemporaryClone();
|
392
|
+
// TODO: This currently discards any rotation information.
|
393
|
+
// Render with (0,0) at (0,0) -- the translation is handled by the viewBox.
|
394
|
+
viewport.resetTransform(math_1.Mat33.identity);
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
viewBoxComponents = [0, 0, screenRectSize.x, screenRectSize.y];
|
398
|
+
}
|
352
399
|
// rect.x -> size of rect in x direction, rect.y -> size of rect in y direction.
|
353
|
-
result.setAttribute('viewBox',
|
354
|
-
result.setAttribute('width', (0, math_1.toRoundedString)(
|
355
|
-
result.setAttribute('height', (0, math_1.toRoundedString)(
|
400
|
+
result.setAttribute('viewBox', viewBoxComponents.map(part => (0, math_1.toRoundedString)(part)).join(' '));
|
401
|
+
result.setAttribute('width', (0, math_1.toRoundedString)(screenRectSize.x));
|
402
|
+
result.setAttribute('height', (0, math_1.toRoundedString)(screenRectSize.y));
|
356
403
|
// Ensure the image can be identified as an SVG if downloaded.
|
357
404
|
// See https://jwatt.org/svg/authoring/
|
358
405
|
result.setAttribute('version', '1.1');
|
359
406
|
result.setAttribute('baseProfile', 'full');
|
360
407
|
result.setAttribute('xmlns', svgNameSpace);
|
361
|
-
|
408
|
+
const renderer = new SVGRenderer(result, viewport, sanitize);
|
409
|
+
if (!visibleRect.eq(viewport.visibleRect)) {
|
410
|
+
renderer.overrideVisibleRect(visibleRect);
|
411
|
+
}
|
412
|
+
return { element: result, renderer };
|
362
413
|
}
|
363
414
|
}
|
364
415
|
exports.default = SVGRenderer;
|