js-draw 0.15.2 → 0.16.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/.github/ISSUE_TEMPLATE/translation.yml +56 -0
- package/CHANGELOG.md +6 -0
- package/dist/bundle.js +1 -1
- package/dist/src/Editor.d.ts +11 -0
- package/dist/src/Editor.js +52 -4
- package/dist/src/EditorImage.d.ts +11 -11
- package/dist/src/EditorImage.js +54 -18
- package/dist/src/Viewport.d.ts +5 -0
- package/dist/src/Viewport.js +11 -0
- package/dist/src/components/AbstractComponent.d.ts +1 -0
- package/dist/src/components/AbstractComponent.js +5 -0
- package/dist/src/components/ImageBackground.d.ts +2 -1
- package/dist/src/components/ImageBackground.js +8 -1
- package/dist/src/localizations/es.js +1 -1
- package/dist/src/toolbar/HTMLToolbar.d.ts +25 -2
- package/dist/src/toolbar/HTMLToolbar.js +127 -15
- package/dist/src/toolbar/IconProvider.d.ts +2 -0
- package/dist/src/toolbar/IconProvider.js +44 -0
- package/dist/src/toolbar/localization.d.ts +5 -0
- package/dist/src/toolbar/localization.js +5 -0
- package/dist/src/toolbar/widgets/ActionButtonWidget.d.ts +3 -1
- package/dist/src/toolbar/widgets/ActionButtonWidget.js +5 -1
- package/dist/src/toolbar/widgets/BaseToolWidget.d.ts +1 -1
- package/dist/src/toolbar/widgets/BaseToolWidget.js +2 -1
- package/dist/src/toolbar/widgets/BaseWidget.d.ts +7 -2
- package/dist/src/toolbar/widgets/BaseWidget.js +23 -1
- package/dist/src/toolbar/widgets/DocumentPropertiesWidget.d.ts +19 -0
- package/dist/src/toolbar/widgets/DocumentPropertiesWidget.js +135 -0
- package/dist/src/toolbar/widgets/OverflowWidget.d.ts +25 -0
- package/dist/src/toolbar/widgets/OverflowWidget.js +65 -0
- package/dist/src/toolbar/widgets/lib.d.ts +1 -0
- package/dist/src/toolbar/widgets/lib.js +1 -0
- package/dist/src/tools/PasteHandler.js +2 -2
- package/dist/src/tools/SelectionTool/Selection.d.ts +2 -1
- package/dist/src/tools/SelectionTool/Selection.js +2 -1
- package/package.json +1 -1
- package/src/Editor.loadFrom.test.ts +24 -0
- package/src/Editor.ts +59 -4
- package/src/EditorImage.ts +66 -23
- package/src/Viewport.ts +13 -0
- package/src/components/AbstractComponent.ts +6 -0
- package/src/components/ImageBackground.test.ts +35 -0
- package/src/components/ImageBackground.ts +10 -1
- package/src/localizations/es.ts +8 -0
- package/src/math/Mat33.test.ts +30 -5
- package/src/rendering/renderers/CanvasRenderer.ts +1 -1
- package/src/toolbar/HTMLToolbar.ts +164 -16
- package/src/toolbar/IconProvider.ts +46 -0
- package/src/toolbar/localization.ts +10 -0
- package/src/toolbar/toolbar.css +2 -0
- package/src/toolbar/widgets/ActionButtonWidget.ts +5 -0
- package/src/toolbar/widgets/BaseToolWidget.ts +3 -1
- package/src/toolbar/widgets/BaseWidget.ts +34 -2
- package/src/toolbar/widgets/DocumentPropertiesWidget.ts +185 -0
- package/src/toolbar/widgets/OverflowWidget.css +9 -0
- package/src/toolbar/widgets/OverflowWidget.ts +83 -0
- package/src/toolbar/widgets/lib.ts +2 -1
- package/src/tools/PasteHandler.ts +3 -2
- package/src/tools/SelectionTool/Selection.ts +2 -1
package/dist/src/Editor.d.ts
CHANGED
@@ -8,6 +8,7 @@ import { Point2 } from './math/Vec2';
|
|
8
8
|
import HTMLToolbar from './toolbar/HTMLToolbar';
|
9
9
|
import { RenderablePathSpec } from './rendering/renderers/AbstractRenderer';
|
10
10
|
import Display, { RenderingMode } from './rendering/Display';
|
11
|
+
import Color4 from './Color4';
|
11
12
|
import Pointer from './Pointer';
|
12
13
|
import Rect2 from './math/Rect2';
|
13
14
|
import { EditorLocalization } from './localization';
|
@@ -222,7 +223,17 @@ export declare class Editor {
|
|
222
223
|
addAndCenterComponents(components: AbstractComponent[], selectComponents?: boolean): Promise<void>;
|
223
224
|
toDataURL(format?: 'image/png' | 'image/jpeg' | 'image/webp'): string;
|
224
225
|
toSVG(): SVGElement;
|
226
|
+
/**
|
227
|
+
* Load editor data from an `ImageLoader` (e.g. an {@link SVGLoader}).
|
228
|
+
*
|
229
|
+
* @see loadFromSVG
|
230
|
+
*/
|
225
231
|
loadFrom(loader: ImageLoader): Promise<void>;
|
232
|
+
private getTopmostBackgroundComponent;
|
233
|
+
/**
|
234
|
+
* Set the background color of the image.
|
235
|
+
*/
|
236
|
+
setBackgroundColor(color: Color4): Command;
|
226
237
|
getImportExportRect(): Rect2;
|
227
238
|
setImportExportRect(imageRect: Rect2): Command;
|
228
239
|
/**
|
package/dist/src/Editor.js
CHANGED
@@ -30,6 +30,8 @@ import untilNextAnimationFrame from './util/untilNextAnimationFrame';
|
|
30
30
|
import fileToBase64 from './util/fileToBase64';
|
31
31
|
import uniteCommands from './commands/uniteCommands';
|
32
32
|
import SelectionTool from './tools/SelectionTool/SelectionTool';
|
33
|
+
import Erase from './commands/Erase';
|
34
|
+
import ImageBackground, { BackgroundType } from './components/ImageBackground';
|
33
35
|
/**
|
34
36
|
* The main entrypoint for the full editor.
|
35
37
|
*
|
@@ -233,14 +235,21 @@ export class Editor {
|
|
233
235
|
});
|
234
236
|
this.notifier.on(EditorEventType.DisplayResized, _event => {
|
235
237
|
this.viewport.updateScreenSize(Vec2.of(this.display.width, this.display.height));
|
238
|
+
this.queueRerender();
|
236
239
|
});
|
237
|
-
|
240
|
+
const handleResize = () => {
|
238
241
|
this.notifier.dispatch(EditorEventType.DisplayResized, {
|
239
242
|
kind: EditorEventType.DisplayResized,
|
240
243
|
newSize: Vec2.of(this.display.width, this.display.height),
|
241
244
|
});
|
242
|
-
|
243
|
-
|
245
|
+
};
|
246
|
+
if ('ResizeObserver' in window) {
|
247
|
+
const resizeObserver = new ResizeObserver(handleResize);
|
248
|
+
resizeObserver.observe(this.container);
|
249
|
+
}
|
250
|
+
else {
|
251
|
+
addEventListener('resize', handleResize);
|
252
|
+
}
|
244
253
|
this.accessibilityControlArea.addEventListener('input', () => {
|
245
254
|
this.accessibilityControlArea.value = '';
|
246
255
|
});
|
@@ -706,7 +715,7 @@ export class Editor {
|
|
706
715
|
return dataURL;
|
707
716
|
}
|
708
717
|
toSVG() {
|
709
|
-
const importExportViewport = this.image.getImportExportViewport();
|
718
|
+
const importExportViewport = this.image.getImportExportViewport().getTemporaryClone();
|
710
719
|
const svgNameSpace = 'http://www.w3.org/2000/svg';
|
711
720
|
const result = document.createElementNS(svgNameSpace, 'svg');
|
712
721
|
const renderer = new SVGRenderer(result, importExportViewport);
|
@@ -728,10 +737,17 @@ export class Editor {
|
|
728
737
|
result.setAttribute('xmlns', svgNameSpace);
|
729
738
|
return result;
|
730
739
|
}
|
740
|
+
/**
|
741
|
+
* Load editor data from an `ImageLoader` (e.g. an {@link SVGLoader}).
|
742
|
+
*
|
743
|
+
* @see loadFromSVG
|
744
|
+
*/
|
731
745
|
loadFrom(loader) {
|
732
746
|
return __awaiter(this, void 0, void 0, function* () {
|
733
747
|
this.showLoadingWarning(0);
|
734
748
|
this.display.setDraftMode(true);
|
749
|
+
const originalBackgrounds = this.image.getBackgroundComponents();
|
750
|
+
const eraseBackgroundCommand = new Erase(originalBackgrounds);
|
735
751
|
yield loader.start((component) => __awaiter(this, void 0, void 0, function* () {
|
736
752
|
yield this.dispatchNoAnnounce(EditorImage.addElement(component));
|
737
753
|
}), (countProcessed, totalToProcess) => {
|
@@ -745,11 +761,43 @@ export class Editor {
|
|
745
761
|
this.dispatchNoAnnounce(this.setImportExportRect(importExportRect), false);
|
746
762
|
this.dispatchNoAnnounce(this.viewport.zoomTo(importExportRect), false);
|
747
763
|
});
|
764
|
+
// Ensure that we don't have multiple overlapping BackgroundComponents. Remove
|
765
|
+
// old BackgroundComponents.
|
766
|
+
// Overlapping BackgroundComponents may cause changing the background color to
|
767
|
+
// not work properly.
|
768
|
+
if (this.image.getBackgroundComponents().length !== originalBackgrounds.length) {
|
769
|
+
yield this.dispatchNoAnnounce(eraseBackgroundCommand);
|
770
|
+
}
|
748
771
|
this.hideLoadingWarning();
|
749
772
|
this.display.setDraftMode(false);
|
750
773
|
this.queueRerender();
|
751
774
|
});
|
752
775
|
}
|
776
|
+
getTopmostBackgroundComponent() {
|
777
|
+
let background = null;
|
778
|
+
// Find a background component, if one exists.
|
779
|
+
// Use the last (topmost) background component if there are multiple.
|
780
|
+
for (const component of this.image.getBackgroundComponents()) {
|
781
|
+
if (component instanceof ImageBackground) {
|
782
|
+
background = component;
|
783
|
+
}
|
784
|
+
}
|
785
|
+
return background;
|
786
|
+
}
|
787
|
+
/**
|
788
|
+
* Set the background color of the image.
|
789
|
+
*/
|
790
|
+
setBackgroundColor(color) {
|
791
|
+
let background = this.getTopmostBackgroundComponent();
|
792
|
+
if (!background) {
|
793
|
+
const backgroundType = color.eq(Color4.transparent) ? BackgroundType.None : BackgroundType.SolidColor;
|
794
|
+
background = new ImageBackground(backgroundType, color);
|
795
|
+
return this.image.addElement(background);
|
796
|
+
}
|
797
|
+
else {
|
798
|
+
return background.updateStyle({ color });
|
799
|
+
}
|
800
|
+
}
|
753
801
|
// Returns the size of the visible region of the output SVG
|
754
802
|
getImportExportRect() {
|
755
803
|
return this.image.getImportExportViewport().visibleRect;
|
@@ -1,12 +1,11 @@
|
|
1
|
-
import Editor from './Editor';
|
2
1
|
import AbstractRenderer from './rendering/renderers/AbstractRenderer';
|
3
2
|
import Viewport from './Viewport';
|
4
3
|
import AbstractComponent from './components/AbstractComponent';
|
5
4
|
import Rect2 from './math/Rect2';
|
6
|
-
import { EditorLocalization } from './localization';
|
7
5
|
import RenderingCache from './rendering/caching/RenderingCache';
|
8
6
|
import SerializableCommand from './commands/SerializableCommand';
|
9
7
|
import EventDispatcher from './EventDispatcher';
|
8
|
+
import Command from './commands/Command';
|
10
9
|
export declare const sortLeavesByZIndex: (leaves: Array<ImageNode>) => void;
|
11
10
|
export declare enum EditorImageEventType {
|
12
11
|
ExportViewportChanged = 0
|
@@ -16,6 +15,7 @@ export type EditorImageNotifier = EventDispatcher<EditorImageEventType, {
|
|
16
15
|
}>;
|
17
16
|
export default class EditorImage {
|
18
17
|
private root;
|
18
|
+
private background;
|
19
19
|
private componentsById;
|
20
20
|
/** Viewport for the exported/imported image. */
|
21
21
|
private importExportViewport;
|
@@ -25,18 +25,17 @@ export default class EditorImage {
|
|
25
25
|
* @returns a `Viewport` for rendering the image when importing/exporting.
|
26
26
|
*/
|
27
27
|
getImportExportViewport(): Viewport;
|
28
|
-
setImportExportRect(imageRect: Rect2):
|
29
|
-
|
30
|
-
unapply(editor: Editor): void;
|
31
|
-
description(_editor: Editor, localizationTable: EditorLocalization): string;
|
32
|
-
onDrop(_editor: Editor): void;
|
33
|
-
};
|
28
|
+
setImportExportRect(imageRect: Rect2): Command;
|
29
|
+
getBackgroundComponents(): AbstractComponent[];
|
34
30
|
findParent(elem: AbstractComponent): ImageNode | null;
|
35
31
|
queueRerenderOf(elem: AbstractComponent): void;
|
36
32
|
/** @internal */
|
37
33
|
renderWithCache(screenRenderer: AbstractRenderer, cache: RenderingCache, viewport: Viewport): void;
|
38
|
-
/**
|
39
|
-
|
34
|
+
/**
|
35
|
+
* Renders all nodes visible from `viewport` (or all nodes if `viewport = null`)
|
36
|
+
* @internal
|
37
|
+
*/
|
38
|
+
render(renderer: AbstractRenderer, viewport: Viewport | null): void;
|
40
39
|
/** Renders all nodes, even ones not within the viewport. @internal */
|
41
40
|
renderAll(renderer: AbstractRenderer): void;
|
42
41
|
/** @returns all elements in the image, sorted by z-index. This can be slow for large images. */
|
@@ -83,6 +82,7 @@ export declare class ImageNode {
|
|
83
82
|
private getChildrenIntersectingRegion;
|
84
83
|
getChildrenOrSelfIntersectingRegion(region: Rect2): ImageNode[];
|
85
84
|
getLeavesIntersectingRegion(region: Rect2, isTooSmall?: TooSmallToRenderCheck): ImageNode[];
|
85
|
+
getChildWithContent(target: AbstractComponent): ImageNode | null;
|
86
86
|
getLeaves(): ImageNode[];
|
87
87
|
addLeaf(leaf: AbstractComponent): ImageNode;
|
88
88
|
getBBox(): Rect2;
|
@@ -90,6 +90,6 @@ export declare class ImageNode {
|
|
90
90
|
private updateParents;
|
91
91
|
private rebalance;
|
92
92
|
remove(): void;
|
93
|
-
render(renderer: AbstractRenderer, visibleRect
|
93
|
+
render(renderer: AbstractRenderer, visibleRect?: Rect2): void;
|
94
94
|
}
|
95
95
|
export {};
|
package/dist/src/EditorImage.js
CHANGED
@@ -20,6 +20,7 @@ export default class EditorImage {
|
|
20
20
|
// @internal
|
21
21
|
constructor() {
|
22
22
|
this.root = new ImageNode();
|
23
|
+
this.background = new ImageNode();
|
23
24
|
this.componentsById = {};
|
24
25
|
this.notifier = new EventDispatcher();
|
25
26
|
this.importExportViewport = new Viewport(() => {
|
@@ -58,15 +59,24 @@ export default class EditorImage {
|
|
58
59
|
}
|
59
60
|
};
|
60
61
|
}
|
61
|
-
// Returns
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
// Returns all components that make up the background of this image. These
|
63
|
+
// components are rendered below all other components.
|
64
|
+
getBackgroundComponents() {
|
65
|
+
const result = [];
|
66
|
+
const leaves = this.background.getLeaves();
|
67
|
+
sortLeavesByZIndex(leaves);
|
68
|
+
for (const leaf of leaves) {
|
69
|
+
const content = leaf.getContent();
|
70
|
+
if (content) {
|
71
|
+
result.push(content);
|
67
72
|
}
|
68
73
|
}
|
69
|
-
return
|
74
|
+
return result;
|
75
|
+
}
|
76
|
+
// Returns the parent of the given element, if it exists.
|
77
|
+
findParent(elem) {
|
78
|
+
var _a;
|
79
|
+
return (_a = this.background.getChildWithContent(elem)) !== null && _a !== void 0 ? _a : this.root.getChildWithContent(elem);
|
70
80
|
}
|
71
81
|
// Forces a re-render of `elem` when the image is next re-rendered as a whole.
|
72
82
|
// Does nothing if `elem` is not in this.
|
@@ -81,19 +91,20 @@ export default class EditorImage {
|
|
81
91
|
}
|
82
92
|
/** @internal */
|
83
93
|
renderWithCache(screenRenderer, cache, viewport) {
|
94
|
+
this.background.render(screenRenderer, viewport.visibleRect);
|
84
95
|
cache.render(screenRenderer, this.root, viewport);
|
85
96
|
}
|
86
|
-
/**
|
97
|
+
/**
|
98
|
+
* Renders all nodes visible from `viewport` (or all nodes if `viewport = null`)
|
99
|
+
* @internal
|
100
|
+
*/
|
87
101
|
render(renderer, viewport) {
|
88
|
-
this.
|
102
|
+
this.background.render(renderer, viewport === null || viewport === void 0 ? void 0 : viewport.visibleRect);
|
103
|
+
this.root.render(renderer, viewport === null || viewport === void 0 ? void 0 : viewport.visibleRect);
|
89
104
|
}
|
90
105
|
/** Renders all nodes, even ones not within the viewport. @internal */
|
91
106
|
renderAll(renderer) {
|
92
|
-
|
93
|
-
sortLeavesByZIndex(leaves);
|
94
|
-
for (const leaf of leaves) {
|
95
|
-
leaf.getContent().render(renderer, leaf.getBBox());
|
96
|
-
}
|
107
|
+
this.render(renderer, null);
|
97
108
|
}
|
98
109
|
/** @returns all elements in the image, sorted by z-index. This can be slow for large images. */
|
99
110
|
getAllElements() {
|
@@ -123,11 +134,19 @@ export default class EditorImage {
|
|
123
134
|
addElementDirectly(elem) {
|
124
135
|
elem.onAddToImage(this);
|
125
136
|
this.componentsById[elem.getId()] = elem;
|
126
|
-
|
137
|
+
// If a background component, add to the background. Else,
|
138
|
+
// add to the normal component tree.
|
139
|
+
const parentTree = elem.isBackground() ? this.background : this.root;
|
140
|
+
return parentTree.addLeaf(elem);
|
127
141
|
}
|
128
142
|
removeElementDirectly(element) {
|
129
143
|
const container = this.findParent(element);
|
130
144
|
container === null || container === void 0 ? void 0 : container.remove();
|
145
|
+
if (container) {
|
146
|
+
this.onDestroyElement(element);
|
147
|
+
return true;
|
148
|
+
}
|
149
|
+
return false;
|
131
150
|
}
|
132
151
|
/**
|
133
152
|
* Returns a command that adds the given element to the `EditorImage`.
|
@@ -140,7 +159,7 @@ export default class EditorImage {
|
|
140
159
|
return new EditorImage.AddElementCommand(elem, applyByFlattening);
|
141
160
|
}
|
142
161
|
/** @see EditorImage.addElement */
|
143
|
-
addElement(elem, applyByFlattening
|
162
|
+
addElement(elem, applyByFlattening) {
|
144
163
|
return EditorImage.addElement(elem, applyByFlattening);
|
145
164
|
}
|
146
165
|
}
|
@@ -247,6 +266,17 @@ export class ImageNode {
|
|
247
266
|
}
|
248
267
|
return result;
|
249
268
|
}
|
269
|
+
// Returns the child of this with the target content or `null` if no
|
270
|
+
// such child exists.
|
271
|
+
getChildWithContent(target) {
|
272
|
+
const candidates = this.getLeavesIntersectingRegion(target.getBBox());
|
273
|
+
for (const candidate of candidates) {
|
274
|
+
if (candidate.getContent() === target) {
|
275
|
+
return candidate;
|
276
|
+
}
|
277
|
+
}
|
278
|
+
return null;
|
279
|
+
}
|
250
280
|
// Returns a list of leaves with this as an ancestor.
|
251
281
|
// Like getLeavesInRegion, but does not check whether ancestors are in a given rectangle
|
252
282
|
getLeaves() {
|
@@ -359,12 +389,12 @@ export class ImageNode {
|
|
359
389
|
// Remove this node and all of its children
|
360
390
|
remove() {
|
361
391
|
var _a;
|
392
|
+
(_a = this.content) === null || _a === void 0 ? void 0 : _a.onRemoveFromImage();
|
362
393
|
if (!this.parent) {
|
363
394
|
this.content = null;
|
364
395
|
this.children = [];
|
365
396
|
return;
|
366
397
|
}
|
367
|
-
(_a = this.content) === null || _a === void 0 ? void 0 : _a.onRemoveFromImage();
|
368
398
|
const oldChildCount = this.parent.children.length;
|
369
399
|
this.parent.children = this.parent.children.filter(node => {
|
370
400
|
return node !== this;
|
@@ -380,7 +410,13 @@ export class ImageNode {
|
|
380
410
|
this.children = [];
|
381
411
|
}
|
382
412
|
render(renderer, visibleRect) {
|
383
|
-
|
413
|
+
let leaves;
|
414
|
+
if (visibleRect) {
|
415
|
+
leaves = this.getLeavesIntersectingRegion(visibleRect, rect => renderer.isTooSmallToRender(rect));
|
416
|
+
}
|
417
|
+
else {
|
418
|
+
leaves = this.getLeaves();
|
419
|
+
}
|
384
420
|
sortLeavesByZIndex(leaves);
|
385
421
|
for (const leaf of leaves) {
|
386
422
|
// Leaves by definition have content
|
package/dist/src/Viewport.d.ts
CHANGED
@@ -16,6 +16,11 @@ export declare class Viewport {
|
|
16
16
|
private inverseTransform;
|
17
17
|
private screenRect;
|
18
18
|
constructor(onTransformChangeCallback: TransformChangeCallback);
|
19
|
+
/**
|
20
|
+
* @returns a temporary copy of `this` that does not notify when modified. This is
|
21
|
+
* useful when rendering with a temporarily different viewport.
|
22
|
+
*/
|
23
|
+
getTemporaryClone(): Viewport;
|
19
24
|
updateScreenSize(screenSize: Vec2): void;
|
20
25
|
/** Get the screen's visible region transformed into canvas space. */
|
21
26
|
get visibleRect(): Rect2;
|
package/dist/src/Viewport.js
CHANGED
@@ -24,6 +24,17 @@ export class Viewport {
|
|
24
24
|
this.resetTransform(Mat33.identity);
|
25
25
|
this.screenRect = Rect2.empty;
|
26
26
|
}
|
27
|
+
/**
|
28
|
+
* @returns a temporary copy of `this` that does not notify when modified. This is
|
29
|
+
* useful when rendering with a temporarily different viewport.
|
30
|
+
*/
|
31
|
+
getTemporaryClone() {
|
32
|
+
const result = new Viewport(() => { });
|
33
|
+
result.transform = this.transform;
|
34
|
+
result.inverseTransform = this.inverseTransform;
|
35
|
+
result.screenRect = this.screenRect;
|
36
|
+
return result;
|
37
|
+
}
|
27
38
|
// @internal
|
28
39
|
updateScreenSize(screenSize) {
|
29
40
|
this.screenRect = this.screenRect.resizedTo(screenSize);
|
@@ -50,6 +50,7 @@ export default abstract class AbstractComponent {
|
|
50
50
|
transformBy(affineTransfm: Mat33): SerializableCommand;
|
51
51
|
setZIndex(newZIndex: number): SerializableCommand;
|
52
52
|
isSelectable(): boolean;
|
53
|
+
isBackground(): boolean;
|
53
54
|
getProportionalRenderingTime(): number;
|
54
55
|
private static transformElementCommandId;
|
55
56
|
private static TransformElementCommand;
|
@@ -94,6 +94,11 @@ export default class AbstractComponent {
|
|
94
94
|
isSelectable() {
|
95
95
|
return true;
|
96
96
|
}
|
97
|
+
// @returns true iff this component should be added to the background, rather than the
|
98
|
+
// foreground of the image.
|
99
|
+
isBackground() {
|
100
|
+
return false;
|
101
|
+
}
|
97
102
|
// @returns an approximation of the proportional time it takes to render this component.
|
98
103
|
// This is intended to be a rough estimate, but, for example, a stroke with two points sould have
|
99
104
|
// a renderingWeight approximately twice that of a stroke with one point.
|
@@ -23,13 +23,14 @@ export default class ImageBackground extends AbstractComponent implements Restyl
|
|
23
23
|
constructor(backgroundType: BackgroundType, mainColor: Color4);
|
24
24
|
getStyle(): ComponentStyle;
|
25
25
|
updateStyle(style: ComponentStyle): SerializableCommand;
|
26
|
-
forceStyle(style: ComponentStyle,
|
26
|
+
forceStyle(style: ComponentStyle, editor: Editor | null): void;
|
27
27
|
onAddToImage(image: EditorImage): void;
|
28
28
|
onRemoveFromImage(): void;
|
29
29
|
private recomputeBBox;
|
30
30
|
render(canvas: AbstractRenderer, visibleRect?: Rect2): void;
|
31
31
|
intersects(lineSegment: LineSegment2): boolean;
|
32
32
|
isSelectable(): boolean;
|
33
|
+
isBackground(): boolean;
|
33
34
|
protected serializeToJSON(): {
|
34
35
|
mainColor: string;
|
35
36
|
backgroundType: BackgroundType;
|
@@ -33,7 +33,7 @@ export default class ImageBackground extends AbstractComponent {
|
|
33
33
|
return createRestyleComponentCommand(this.getStyle(), style, this);
|
34
34
|
}
|
35
35
|
// @internal
|
36
|
-
forceStyle(style,
|
36
|
+
forceStyle(style, editor) {
|
37
37
|
const fill = style.color;
|
38
38
|
if (!fill) {
|
39
39
|
return;
|
@@ -45,6 +45,10 @@ export default class ImageBackground extends AbstractComponent {
|
|
45
45
|
else {
|
46
46
|
this.backgroundType = BackgroundType.SolidColor;
|
47
47
|
}
|
48
|
+
if (editor) {
|
49
|
+
editor.image.queueRerenderOf(this);
|
50
|
+
editor.queueRerender();
|
51
|
+
}
|
48
52
|
}
|
49
53
|
onAddToImage(image) {
|
50
54
|
if (this.viewportSizeChangeListener) {
|
@@ -96,6 +100,9 @@ export default class ImageBackground extends AbstractComponent {
|
|
96
100
|
isSelectable() {
|
97
101
|
return false;
|
98
102
|
}
|
103
|
+
isBackground() {
|
104
|
+
return true;
|
105
|
+
}
|
99
106
|
serializeToJSON() {
|
100
107
|
return {
|
101
108
|
mainColor: this.mainColor.toHexString(),
|
@@ -14,5 +14,5 @@ const localization = Object.assign(Object.assign({}, defaultEditorLocalization),
|
|
14
14
|
return `Color fue cambiado a ${color}`;
|
15
15
|
}, keyboardPanZoom: 'Mover la pantalla con el teclado', penTool: function (penId) {
|
16
16
|
return `Lapiz ${penId}`;
|
17
|
-
}, selectionTool: 'Selecciona', eraserTool: 'Borrador', textTool: 'Texto', enterTextToInsert: 'Entra texto', rerenderAsText: 'Redibuja la pantalla al texto', image: 'Imagen', imageSize: (size, units) => `Tamaño del imagen: ${size} ${units}`, imageLoadError: (message) => `Error cargando imagen: ${message}
|
17
|
+
}, selectionTool: 'Selecciona', eraserTool: 'Borrador', textTool: 'Texto', enterTextToInsert: 'Entra texto', textSize: 'Tamaño', rerenderAsText: 'Redibuja la pantalla al texto', lockRotation: 'Bloquea rotación', image: 'Imagen', imageSize: (size, units) => `Tamaño del imagen: ${size} ${units}`, imageLoadError: (message) => `Error cargando imagen: ${message}`, toggleOverflow: 'Más', documentProperties: 'Fondo', imageWidthOption: 'Ancho: ', imageHeightOption: 'Alto: ', backgroundColor: 'Color de fondo: ' });
|
18
18
|
export default localization;
|
@@ -12,12 +12,19 @@ export default class HTMLToolbar {
|
|
12
12
|
private editor;
|
13
13
|
private localizationTable;
|
14
14
|
private container;
|
15
|
-
private
|
15
|
+
private resizeObserver;
|
16
|
+
private listeners;
|
17
|
+
private widgetsById;
|
18
|
+
private widgetList;
|
19
|
+
private overflowWidget;
|
16
20
|
private static colorisStarted;
|
17
21
|
private updateColoris;
|
18
22
|
/** @internal */
|
19
23
|
constructor(editor: Editor, parent: HTMLElement, localizationTable?: ToolbarLocalization);
|
20
24
|
setupColorPickers(): void;
|
25
|
+
private reLayoutQueued;
|
26
|
+
private queueReLayout;
|
27
|
+
private reLayout;
|
21
28
|
/**
|
22
29
|
* Adds an `ActionButtonWidget` or `BaseToolWidget`. The widget should not have already have a parent
|
23
30
|
* (i.e. its `addTo` method should not have been called).
|
@@ -63,17 +70,33 @@ export default class HTMLToolbar {
|
|
63
70
|
*
|
64
71
|
* @return The added button.
|
65
72
|
*/
|
66
|
-
addActionButton(title: string | ActionButtonIcon, command: () => void): BaseWidget;
|
73
|
+
addActionButton(title: string | ActionButtonIcon, command: () => void, mustBeToplevel?: boolean): BaseWidget;
|
67
74
|
addUndoRedoButtons(): void;
|
68
75
|
addDefaultToolWidgets(): void;
|
69
76
|
addDefaultActionButtons(): void;
|
77
|
+
/**
|
78
|
+
* Adds a widget that toggles the overflow menu. Call `addOverflowWidget` to ensure
|
79
|
+
* that this widget is in the correct space (if shown).
|
80
|
+
*
|
81
|
+
* @example
|
82
|
+
* ```ts
|
83
|
+
* toolbar.addDefaultToolWidgets();
|
84
|
+
* toolbar.addOverflowWidget();
|
85
|
+
* toolbar.addDefaultActionButtons();
|
86
|
+
* ```
|
87
|
+
* shows the overflow widget between the default tool widgets and the default action buttons,
|
88
|
+
* if shown.
|
89
|
+
*/
|
90
|
+
addOverflowWidget(): void;
|
70
91
|
/**
|
71
92
|
* Adds both the default tool widgets and action buttons. Equivalent to
|
72
93
|
* ```ts
|
73
94
|
* toolbar.addDefaultToolWidgets();
|
95
|
+
* toolbar.addOverflowWidget();
|
74
96
|
* toolbar.addDefaultActionButtons();
|
75
97
|
* ```
|
76
98
|
*/
|
77
99
|
addDefaults(): void;
|
100
|
+
remove(): void;
|
78
101
|
}
|
79
102
|
export {};
|