js-draw 0.1.11 → 0.1.12
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/CHANGELOG.md +7 -0
- package/dist/bundle.js +1 -1
- package/dist/src/Editor.d.ts +4 -2
- package/dist/src/Editor.js +30 -10
- package/dist/src/EditorImage.d.ts +1 -1
- package/dist/src/EditorImage.js +2 -2
- package/dist/src/Pointer.d.ts +1 -1
- package/dist/src/Pointer.js +1 -1
- package/dist/src/SVGLoader.d.ts +1 -1
- package/dist/src/SVGLoader.js +14 -6
- package/dist/src/Viewport.d.ts +8 -25
- package/dist/src/Viewport.js +15 -10
- package/dist/src/commands/Command.d.ts +2 -2
- package/dist/src/commands/Command.js +4 -4
- package/dist/src/commands/Duplicate.d.ts +1 -1
- package/dist/src/commands/Duplicate.js +1 -1
- package/dist/src/commands/Erase.d.ts +1 -1
- package/dist/src/commands/Erase.js +1 -1
- package/dist/src/commands/localization.d.ts +1 -1
- package/dist/src/components/AbstractComponent.d.ts +3 -3
- package/dist/src/components/AbstractComponent.js +2 -2
- package/dist/src/components/SVGGlobalAttributesObject.d.ts +3 -3
- package/dist/src/components/SVGGlobalAttributesObject.js +1 -1
- package/dist/src/components/Stroke.d.ts +4 -4
- package/dist/src/components/Stroke.js +2 -2
- package/dist/src/components/Text.d.ts +3 -3
- package/dist/src/components/Text.js +3 -3
- package/dist/src/components/UnknownSVGObject.d.ts +3 -3
- package/dist/src/components/UnknownSVGObject.js +1 -1
- package/dist/src/components/builders/ArrowBuilder.d.ts +1 -1
- package/dist/src/components/builders/ArrowBuilder.js +1 -1
- package/dist/src/components/builders/FreehandLineBuilder.d.ts +8 -3
- package/dist/src/components/builders/FreehandLineBuilder.js +142 -71
- package/dist/src/components/builders/LineBuilder.d.ts +1 -1
- package/dist/src/components/builders/LineBuilder.js +1 -1
- package/dist/src/components/builders/RectangleBuilder.d.ts +1 -1
- package/dist/src/components/builders/RectangleBuilder.js +3 -3
- package/dist/src/components/builders/types.d.ts +1 -1
- package/dist/src/localization.d.ts +1 -0
- package/dist/src/localization.js +5 -1
- package/dist/src/localizations/es.js +1 -1
- package/dist/src/{geometry → math}/LineSegment2.d.ts +0 -0
- package/dist/src/{geometry → math}/LineSegment2.js +0 -0
- package/dist/src/{geometry → math}/Mat33.d.ts +0 -0
- package/dist/src/{geometry → math}/Mat33.js +0 -0
- package/dist/src/{geometry → math}/Path.d.ts +2 -1
- package/dist/src/{geometry → math}/Path.js +58 -51
- package/dist/src/{geometry → math}/Rect2.d.ts +0 -0
- package/dist/src/{geometry → math}/Rect2.js +0 -0
- package/dist/src/{geometry → math}/Vec2.d.ts +0 -0
- package/dist/src/{geometry → math}/Vec2.js +0 -0
- package/dist/src/{geometry → math}/Vec3.d.ts +1 -1
- package/dist/src/{geometry → math}/Vec3.js +1 -1
- package/dist/src/math/rounding.d.ts +3 -0
- package/dist/src/math/rounding.js +120 -0
- package/dist/src/rendering/Display.d.ts +3 -1
- package/dist/src/rendering/Display.js +16 -10
- package/dist/src/rendering/caching/CacheRecord.d.ts +2 -2
- package/dist/src/rendering/caching/CacheRecord.js +1 -1
- package/dist/src/rendering/caching/CacheRecordManager.d.ts +1 -1
- package/dist/src/rendering/caching/RenderingCache.js +1 -1
- package/dist/src/rendering/caching/RenderingCacheNode.d.ts +2 -1
- package/dist/src/rendering/caching/RenderingCacheNode.js +18 -7
- package/dist/src/rendering/caching/testUtils.js +1 -1
- package/dist/src/rendering/caching/types.d.ts +1 -1
- package/dist/src/rendering/localization.d.ts +2 -0
- package/dist/src/rendering/localization.js +2 -0
- package/dist/src/rendering/renderers/AbstractRenderer.d.ts +4 -4
- package/dist/src/rendering/renderers/AbstractRenderer.js +2 -2
- package/dist/src/rendering/renderers/CanvasRenderer.d.ts +4 -4
- package/dist/src/rendering/renderers/CanvasRenderer.js +1 -1
- package/dist/src/rendering/renderers/DummyRenderer.d.ts +4 -4
- package/dist/src/rendering/renderers/DummyRenderer.js +1 -1
- package/dist/src/rendering/renderers/SVGRenderer.d.ts +3 -3
- package/dist/src/rendering/renderers/SVGRenderer.js +8 -2
- package/dist/src/rendering/renderers/TextOnlyRenderer.d.ts +5 -3
- package/dist/src/rendering/renderers/TextOnlyRenderer.js +13 -3
- package/dist/src/toolbar/icons.d.ts +3 -0
- package/dist/src/toolbar/icons.js +142 -132
- package/dist/src/toolbar/localization.d.ts +2 -1
- package/dist/src/toolbar/localization.js +2 -1
- package/dist/src/toolbar/makeColorInput.js +2 -1
- package/dist/src/toolbar/widgets/ActionButtonWidget.d.ts +13 -0
- package/dist/src/toolbar/widgets/ActionButtonWidget.js +21 -0
- package/dist/src/toolbar/widgets/BaseWidget.js +2 -0
- package/dist/src/toolbar/widgets/HandToolWidget.js +3 -3
- package/dist/src/toolbar/widgets/SelectionWidget.d.ts +0 -1
- package/dist/src/toolbar/widgets/SelectionWidget.js +23 -30
- package/dist/src/tools/Eraser.js +1 -1
- package/dist/src/tools/PanZoom.d.ts +1 -1
- package/dist/src/tools/PanZoom.js +24 -14
- package/dist/src/tools/SelectionTool.d.ts +3 -3
- package/dist/src/tools/SelectionTool.js +6 -6
- package/dist/src/tools/TextTool.js +1 -1
- package/dist/src/types.d.ts +4 -4
- package/package.json +1 -1
- package/src/Editor.ts +34 -12
- package/src/EditorImage.test.ts +2 -4
- package/src/EditorImage.ts +2 -2
- package/src/Pointer.ts +1 -1
- package/src/SVGLoader.ts +14 -6
- package/src/Viewport.ts +19 -17
- package/src/commands/Command.ts +5 -5
- package/src/commands/Duplicate.ts +1 -1
- package/src/commands/Erase.ts +1 -1
- package/src/commands/localization.ts +1 -1
- package/src/components/AbstractComponent.ts +4 -4
- package/src/components/SVGGlobalAttributesObject.ts +3 -3
- package/src/components/Stroke.test.ts +3 -5
- package/src/components/Stroke.ts +4 -4
- package/src/components/Text.test.ts +2 -2
- package/src/components/Text.ts +3 -3
- package/src/components/UnknownSVGObject.ts +3 -3
- package/src/components/builders/ArrowBuilder.ts +2 -2
- package/src/components/builders/FreehandLineBuilder.ts +190 -80
- package/src/components/builders/LineBuilder.ts +2 -2
- package/src/components/builders/RectangleBuilder.ts +3 -3
- package/src/components/builders/types.ts +1 -1
- package/src/localization.ts +6 -0
- package/src/localizations/es.ts +2 -1
- package/src/{geometry → math}/LineSegment2.test.ts +0 -0
- package/src/{geometry → math}/LineSegment2.ts +0 -0
- package/src/{geometry → math}/Mat33.test.ts +0 -0
- package/src/{geometry → math}/Mat33.ts +0 -0
- package/src/{geometry → math}/Path.fromString.test.ts +0 -0
- package/src/{geometry → math}/Path.test.ts +0 -0
- package/src/{geometry → math}/Path.toString.test.ts +11 -2
- package/src/{geometry → math}/Path.ts +60 -57
- package/src/{geometry → math}/Rect2.test.ts +0 -0
- package/src/{geometry → math}/Rect2.ts +0 -0
- package/src/{geometry → math}/Vec2.test.ts +0 -0
- package/src/{geometry → math}/Vec2.ts +0 -0
- package/src/{geometry → math}/Vec3.test.ts +0 -0
- package/src/{geometry → math}/Vec3.ts +2 -2
- package/src/math/rounding.test.ts +40 -0
- package/src/math/rounding.ts +145 -0
- package/src/rendering/Display.ts +18 -10
- package/src/rendering/caching/CacheRecord.test.ts +2 -2
- package/src/rendering/caching/CacheRecord.ts +2 -2
- package/src/rendering/caching/CacheRecordManager.ts +1 -1
- package/src/rendering/caching/RenderingCache.test.ts +3 -3
- package/src/rendering/caching/RenderingCache.ts +1 -1
- package/src/rendering/caching/RenderingCacheNode.ts +23 -7
- package/src/rendering/caching/testUtils.ts +1 -1
- package/src/rendering/caching/types.ts +1 -1
- package/src/rendering/localization.ts +4 -0
- package/src/rendering/renderers/AbstractRenderer.ts +4 -4
- package/src/rendering/renderers/CanvasRenderer.ts +4 -4
- package/src/rendering/renderers/DummyRenderer.test.ts +2 -2
- package/src/rendering/renderers/DummyRenderer.ts +4 -4
- package/src/rendering/renderers/SVGRenderer.ts +10 -4
- package/src/rendering/renderers/TextOnlyRenderer.ts +17 -6
- package/src/toolbar/icons.ts +157 -137
- package/src/toolbar/localization.ts +4 -2
- package/src/toolbar/makeColorInput.ts +2 -1
- package/src/toolbar/toolbar.css +1 -1
- package/src/toolbar/widgets/ActionButtonWidget.ts +31 -0
- package/src/toolbar/widgets/BaseWidget.ts +2 -0
- package/src/toolbar/widgets/HandToolWidget.ts +3 -3
- package/src/toolbar/widgets/SelectionWidget.ts +46 -41
- package/src/tools/Eraser.ts +2 -2
- package/src/tools/PanZoom.ts +28 -16
- package/src/tools/SelectionTool.test.ts +2 -4
- package/src/tools/SelectionTool.ts +6 -6
- package/src/tools/TextTool.ts +2 -2
- package/src/tools/UndoRedoShortcut.test.ts +1 -1
- package/src/types.ts +4 -4
package/src/toolbar/icons.ts
CHANGED
@@ -2,7 +2,7 @@ import Color4 from '../Color4';
|
|
2
2
|
import { ComponentBuilderFactory } from '../components/builders/types';
|
3
3
|
import { TextStyle } from '../components/Text';
|
4
4
|
import EventDispatcher from '../EventDispatcher';
|
5
|
-
import { Vec2 } from '../
|
5
|
+
import { Vec2 } from '../math/Vec2';
|
6
6
|
import SVGRenderer from '../rendering/renderers/SVGRenderer';
|
7
7
|
import Pen from '../tools/Pen';
|
8
8
|
import { StrokeDataPoint } from '../types';
|
@@ -103,152 +103,141 @@ export const makeSelectionIcon = () => {
|
|
103
103
|
return icon;
|
104
104
|
};
|
105
105
|
|
106
|
-
|
106
|
+
const pathIcon = (
|
107
|
+
pathData: string,
|
108
|
+
fill: string = 'var(--icon-color)',
|
109
|
+
strokeColor: string = 'none',
|
110
|
+
strokeWidth: string = '0px',
|
111
|
+
) => {
|
107
112
|
const icon = document.createElementNS(svgNamespace, 'svg');
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
5,30
|
115
|
-
H 90
|
116
|
-
V 30
|
117
|
-
C 90,20 75,20 75,30
|
118
|
-
V 60
|
119
|
-
20
|
120
|
-
C 75,10 60,10 60,20
|
121
|
-
V 60
|
122
|
-
15
|
123
|
-
C 60,5 45,5 45,15
|
124
|
-
V 60
|
125
|
-
25
|
126
|
-
C 45,15 30,15 30,25
|
127
|
-
V 60
|
128
|
-
75
|
129
|
-
L 25,60
|
130
|
-
C 20,45 10,50 10,60
|
131
|
-
Z'
|
132
|
-
|
133
|
-
fill='none'
|
134
|
-
style='
|
135
|
-
stroke: var(--icon-color);
|
136
|
-
stroke-width: 2;
|
137
|
-
'
|
138
|
-
/>
|
139
|
-
</g>
|
140
|
-
`;
|
113
|
+
const path = document.createElementNS(svgNamespace, 'path');
|
114
|
+
path.setAttribute('d', pathData);
|
115
|
+
path.style.fill = fill;
|
116
|
+
path.style.stroke = strokeColor;
|
117
|
+
path.style.strokeWidth = strokeWidth;
|
118
|
+
icon.appendChild(path);
|
141
119
|
icon.setAttribute('viewBox', '0 0 100 100');
|
120
|
+
|
142
121
|
return icon;
|
143
122
|
};
|
144
123
|
|
124
|
+
export const makeHandToolIcon = () => {
|
125
|
+
const fill = 'none';
|
126
|
+
const strokeColor = 'var(--icon-color)';
|
127
|
+
const strokeWidth = '3';
|
128
|
+
|
129
|
+
// Draw a cursor-like shape (like some of the other icons, made with Inkscape)
|
130
|
+
return pathIcon(`
|
131
|
+
m 10,60
|
132
|
+
5,30
|
133
|
+
H 90
|
134
|
+
V 30
|
135
|
+
C 90,20 75,20 75,30
|
136
|
+
V 60
|
137
|
+
20
|
138
|
+
C 75,10 60,10 60,20
|
139
|
+
V 60
|
140
|
+
15
|
141
|
+
C 60,5 45,5 45,15
|
142
|
+
V 60
|
143
|
+
25
|
144
|
+
C 45,15 30,15 30,25
|
145
|
+
V 60
|
146
|
+
75
|
147
|
+
L 25,60
|
148
|
+
C 20,45 10,50 10,60
|
149
|
+
Z
|
150
|
+
`, fill, strokeColor, strokeWidth);
|
151
|
+
};
|
152
|
+
|
145
153
|
export const makeTouchPanningIcon = () => {
|
146
|
-
const
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
m 33.75,0
|
156
|
-
L 50,17
|
157
|
-
V 5.5
|
158
|
-
Z
|
159
|
-
|
160
|
-
M 5,40.7
|
161
|
-
v 11.7
|
162
|
-
h 11.25
|
163
|
-
z
|
164
|
-
|
165
|
-
M 26,19
|
166
|
-
C 19.8,19.4 17.65,30.4 21.9,34.8
|
167
|
-
L 50,70
|
168
|
-
H 27.5
|
169
|
-
c -11.25,0 -11.25,17.6 0,17.6
|
170
|
-
H 61.25
|
171
|
-
C 94.9,87.8 95,87.6 95,40.7 78.125,23 67,29 55.6,46.5
|
172
|
-
L 33.1,23
|
173
|
-
C 30.3125,20.128192 27.9,19 25.830078,19.119756
|
174
|
-
Z
|
175
|
-
'
|
176
|
-
fill='none'
|
177
|
-
style='
|
178
|
-
stroke: var(--icon-color);
|
179
|
-
stroke-width: 2;
|
180
|
-
'
|
181
|
-
/>
|
182
|
-
`;
|
154
|
+
const fill = 'none';
|
155
|
+
const strokeColor = 'var(--icon-color)';
|
156
|
+
const strokeWidth = '3';
|
157
|
+
|
158
|
+
return pathIcon(`
|
159
|
+
M 5,5.5
|
160
|
+
V 17.2
|
161
|
+
L 16.25,5.46
|
162
|
+
Z
|
183
163
|
|
184
|
-
|
185
|
-
|
164
|
+
m 33.75,0
|
165
|
+
L 50,17
|
166
|
+
V 5.5
|
167
|
+
Z
|
168
|
+
|
169
|
+
M 5,40.7
|
170
|
+
v 11.7
|
171
|
+
h 11.25
|
172
|
+
z
|
173
|
+
|
174
|
+
M 26,19
|
175
|
+
C 19.8,19.4 17.65,30.4 21.9,34.8
|
176
|
+
L 50,70
|
177
|
+
H 27.5
|
178
|
+
c -11.25,0 -11.25,17.6 0,17.6
|
179
|
+
H 61.25
|
180
|
+
C 94.9,87.8 95,87.6 95,40.7 78.125,23 67,29 55.6,46.5
|
181
|
+
L 33.1,23
|
182
|
+
C 30.3125,20.128192 27.9,19 25.830078,19.119756
|
183
|
+
Z
|
184
|
+
`, fill, strokeColor, strokeWidth);
|
186
185
|
};
|
187
186
|
|
188
187
|
export const makeAllDevicePanningIcon = () => {
|
189
|
-
const
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
fill='none'
|
243
|
-
style='
|
244
|
-
stroke: var(--icon-color);
|
245
|
-
stroke-width: 2;
|
246
|
-
'
|
247
|
-
/>
|
248
|
-
`;
|
249
|
-
|
250
|
-
icon.setAttribute('viewBox', '0 0 100 100');
|
251
|
-
return icon;
|
188
|
+
const fill = 'none';
|
189
|
+
const strokeColor = 'var(--icon-color)';
|
190
|
+
const strokeWidth = '3';
|
191
|
+
return pathIcon(`
|
192
|
+
M 5 5
|
193
|
+
L 5 17.5
|
194
|
+
17.5 5
|
195
|
+
5 5
|
196
|
+
z
|
197
|
+
|
198
|
+
M 42.5 5
|
199
|
+
L 55 17.5
|
200
|
+
55 5
|
201
|
+
42.5 5
|
202
|
+
z
|
203
|
+
|
204
|
+
M 70 10
|
205
|
+
L 70 21
|
206
|
+
61 15
|
207
|
+
55.5 23
|
208
|
+
66 30
|
209
|
+
56 37
|
210
|
+
61 45
|
211
|
+
70 39
|
212
|
+
70 50
|
213
|
+
80 50
|
214
|
+
80 39
|
215
|
+
89 45
|
216
|
+
95 36
|
217
|
+
84 30
|
218
|
+
95 23
|
219
|
+
89 15
|
220
|
+
80 21
|
221
|
+
80 10
|
222
|
+
70 10
|
223
|
+
z
|
224
|
+
|
225
|
+
M 27.5 26.25
|
226
|
+
L 27.5 91.25
|
227
|
+
L 43.75 83.125
|
228
|
+
L 52 99
|
229
|
+
L 68 91
|
230
|
+
L 60 75
|
231
|
+
L 76.25 66.875
|
232
|
+
L 27.5 26.25
|
233
|
+
z
|
234
|
+
|
235
|
+
M 5 42.5
|
236
|
+
L 5 55
|
237
|
+
L 17.5 55
|
238
|
+
L 5 42.5
|
239
|
+
z
|
240
|
+
`, fill, strokeColor, strokeWidth);
|
252
241
|
};
|
253
242
|
|
254
243
|
export const makeZoomIcon = () => {
|
@@ -417,3 +406,34 @@ export const makePipetteIcon = (color?: Color4) => {
|
|
417
406
|
icon.setAttribute('viewBox', '0 0 100 100');
|
418
407
|
return icon;
|
419
408
|
};
|
409
|
+
|
410
|
+
export const makeResizeViewportIcon = () => {
|
411
|
+
return pathIcon(`
|
412
|
+
M 75 5 75 10 90 10 90 25 95 25 95 5 75 5 z
|
413
|
+
M 15 15 15 30 20 30 20 20 30 20 30 15 15 15 z
|
414
|
+
M 84 15 82 17 81 16 81 20 85 20 84 19 86 17 84 15 z
|
415
|
+
M 26 24 24 26 26 28 25 29 29 29 29 25 28 26 26 24 z
|
416
|
+
M 25 71 26 72 24 74 26 76 28 74 29 75 29 71 25 71 z
|
417
|
+
M 15 75 15 85 25 85 25 80 20 80 20 75 15 75 z
|
418
|
+
M 90 75 90 90 75 90 75 95 95 95 95 75 90 75 z
|
419
|
+
M 81 81 81 85 82 84 84 86 86 84 84 82 85 81 81 81 z
|
420
|
+
`);
|
421
|
+
};
|
422
|
+
|
423
|
+
export const makeDuplicateSelectionIcon = () => {
|
424
|
+
return pathIcon(`
|
425
|
+
M 45,10 45,55 90,55 90,10 45,10 z
|
426
|
+
M 10,25 10,90 70,90 70,60 40,60 40,25 10,25 z
|
427
|
+
`);
|
428
|
+
};
|
429
|
+
|
430
|
+
export const makeDeleteSelectionIcon = () => {
|
431
|
+
const strokeWidth = '5px';
|
432
|
+
const strokeColor = 'var(--icon-color)';
|
433
|
+
const fillColor = 'none';
|
434
|
+
|
435
|
+
return pathIcon(`
|
436
|
+
M 10,10 90,90
|
437
|
+
M 10,90 90,10
|
438
|
+
`, fillColor, strokeColor, strokeWidth);
|
439
|
+
};
|
@@ -19,7 +19,8 @@ export interface ToolbarLocalization {
|
|
19
19
|
resizeImageToSelection: string;
|
20
20
|
deleteSelection: string;
|
21
21
|
duplicateSelection: string;
|
22
|
-
|
22
|
+
pickColorFromScreen: string;
|
23
|
+
clickToPickColorAnnouncement: string;
|
23
24
|
undo: string;
|
24
25
|
redo: string;
|
25
26
|
zoom: string;
|
@@ -48,7 +49,8 @@ export const defaultToolbarLocalization: ToolbarLocalization = {
|
|
48
49
|
undo: 'Undo',
|
49
50
|
redo: 'Redo',
|
50
51
|
selectObjectType: 'Object type: ',
|
51
|
-
|
52
|
+
pickColorFromScreen: 'Pick color from screen',
|
53
|
+
clickToPickColorAnnouncement: 'Click on the screen to pick a color',
|
52
54
|
selectionToolKeyboardShortcuts: 'Selection tool: Use arrow keys to move selected items, lowercase/uppercase ‘i’ and ‘o’ to resize.',
|
53
55
|
|
54
56
|
touchPanning: 'Touchscreen panning',
|
@@ -69,7 +69,7 @@ export const makeColorInput = (editor: Editor, onColorChange: OnColorChangeListe
|
|
69
69
|
const addPipetteTool = (editor: Editor, container: HTMLElement, onColorChange: OnColorChangeListener) => {
|
70
70
|
const pipetteButton = document.createElement('button');
|
71
71
|
pipetteButton.classList.add('pipetteButton');
|
72
|
-
pipetteButton.title = editor.localization.
|
72
|
+
pipetteButton.title = editor.localization.pickColorFromScreen;
|
73
73
|
pipetteButton.setAttribute('alt', pipetteButton.title);
|
74
74
|
|
75
75
|
const updatePipetteIcon = (color?: Color4) => {
|
@@ -111,6 +111,7 @@ const addPipetteTool = (editor: Editor, container: HTMLElement, onColorChange: O
|
|
111
111
|
);
|
112
112
|
if (pipetteTool) {
|
113
113
|
pipetteButton.classList.add('active');
|
114
|
+
editor.announceForAccessibility(editor.localization.clickToPickColorAnnouncement);
|
114
115
|
}
|
115
116
|
};
|
116
117
|
|
package/src/toolbar/toolbar.css
CHANGED
@@ -83,7 +83,7 @@
|
|
83
83
|
min-height: 30px;
|
84
84
|
}
|
85
85
|
|
86
|
-
.toolbar-toolContainer.selected .toolbar-button {
|
86
|
+
.toolbar-toolContainer.selected > .toolbar-button {
|
87
87
|
background-color: var(--secondary-background-color);
|
88
88
|
color: var(--secondary-foreground-color);
|
89
89
|
--icon-color: var(--secondary-foreground-color);
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import Editor from '../../Editor';
|
2
|
+
import { ToolbarLocalization } from '../localization';
|
3
|
+
import BaseWidget from './BaseWidget';
|
4
|
+
|
5
|
+
export default class ActionButtonWidget extends BaseWidget {
|
6
|
+
public constructor(
|
7
|
+
editor: Editor, localizationTable: ToolbarLocalization,
|
8
|
+
protected makeIcon: ()=> Element,
|
9
|
+
protected title: string,
|
10
|
+
|
11
|
+
protected clickAction: ()=>void,
|
12
|
+
) {
|
13
|
+
super(editor, localizationTable);
|
14
|
+
}
|
15
|
+
|
16
|
+
protected handleClick() {
|
17
|
+
this.clickAction();
|
18
|
+
}
|
19
|
+
|
20
|
+
protected getTitle(): string {
|
21
|
+
return this.title;
|
22
|
+
}
|
23
|
+
|
24
|
+
protected createIcon(): Element {
|
25
|
+
return this.makeIcon();
|
26
|
+
}
|
27
|
+
|
28
|
+
protected fillDropdown(_dropdown: HTMLElement): boolean {
|
29
|
+
return false;
|
30
|
+
}
|
31
|
+
}
|
@@ -137,8 +137,10 @@ export default abstract class BaseWidget {
|
|
137
137
|
this.disabled = disabled;
|
138
138
|
if (this.disabled) {
|
139
139
|
this.button.classList.add('disabled');
|
140
|
+
this.button.setAttribute('aria-disabled', 'true');
|
140
141
|
} else {
|
141
142
|
this.button.classList.remove('disabled');
|
143
|
+
this.button.removeAttribute('aria-disabled');
|
142
144
|
}
|
143
145
|
}
|
144
146
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import Editor from '../../Editor';
|
2
|
-
import Mat33 from '../../
|
2
|
+
import Mat33 from '../../math/Mat33';
|
3
3
|
import PanZoom, { PanZoomMode } from '../../tools/PanZoom';
|
4
4
|
import { EditorEventType } from '../../types';
|
5
5
|
import Viewport from '../../Viewport';
|
@@ -53,7 +53,7 @@ const makeZoomControl = (localizationTable: ToolbarLocalization, editor: Editor)
|
|
53
53
|
const zoomBy = (factor: number) => {
|
54
54
|
const screenCenter = editor.viewport.visibleRect.center;
|
55
55
|
const transformUpdate = Mat33.scaling2D(factor, screenCenter);
|
56
|
-
editor.dispatch(
|
56
|
+
editor.dispatch(Viewport.transformBy(transformUpdate), false);
|
57
57
|
};
|
58
58
|
|
59
59
|
increaseButton.onclick = () => {
|
@@ -65,7 +65,7 @@ const makeZoomControl = (localizationTable: ToolbarLocalization, editor: Editor)
|
|
65
65
|
};
|
66
66
|
|
67
67
|
resetViewButton.onclick = () => {
|
68
|
-
editor.dispatch(
|
68
|
+
editor.dispatch(Viewport.transformBy(
|
69
69
|
editor.viewport.canvasToScreenTransform.inverse()
|
70
70
|
), true);
|
71
71
|
};
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import Editor from '../../Editor';
|
2
2
|
import SelectionTool from '../../tools/SelectionTool';
|
3
3
|
import { EditorEventType } from '../../types';
|
4
|
-
import { makeSelectionIcon } from '../icons';
|
4
|
+
import { makeDeleteSelectionIcon, makeDuplicateSelectionIcon, makeResizeViewportIcon, makeSelectionIcon } from '../icons';
|
5
5
|
import { ToolbarLocalization } from '../localization';
|
6
|
+
import ActionButtonWidget from './ActionButtonWidget';
|
6
7
|
import BaseToolWidget from './BaseToolWidget';
|
7
8
|
|
8
9
|
export class SelectionWidget extends BaseToolWidget {
|
@@ -10,44 +11,46 @@ export class SelectionWidget extends BaseToolWidget {
|
|
10
11
|
editor: Editor, private tool: SelectionTool, localization: ToolbarLocalization
|
11
12
|
) {
|
12
13
|
super(editor, tool, localization);
|
13
|
-
}
|
14
|
-
|
15
|
-
protected getTitle(): string {
|
16
|
-
return this.localizationTable.select;
|
17
|
-
}
|
18
|
-
|
19
|
-
protected createIcon(): Element {
|
20
|
-
return makeSelectionIcon();
|
21
|
-
}
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
deleteButton
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
15
|
+
const resizeButton = new ActionButtonWidget(
|
16
|
+
editor, localization,
|
17
|
+
makeResizeViewportIcon,
|
18
|
+
this.localizationTable.resizeImageToSelection,
|
19
|
+
() => {
|
20
|
+
const selection = this.tool.getSelection();
|
21
|
+
this.editor.dispatch(this.editor.setImportExportRect(selection!.region));
|
22
|
+
},
|
23
|
+
);
|
24
|
+
const deleteButton = new ActionButtonWidget(
|
25
|
+
editor, localization,
|
26
|
+
makeDeleteSelectionIcon,
|
27
|
+
this.localizationTable.deleteSelection,
|
28
|
+
() => {
|
29
|
+
const selection = this.tool.getSelection();
|
30
|
+
this.editor.dispatch(selection!.deleteSelectedObjects());
|
31
|
+
this.tool.clearSelection();
|
32
|
+
},
|
33
|
+
);
|
34
|
+
const duplicateButton = new ActionButtonWidget(
|
35
|
+
editor, localization,
|
36
|
+
makeDuplicateSelectionIcon,
|
37
|
+
this.localizationTable.duplicateSelection,
|
38
|
+
() => {
|
39
|
+
const selection = this.tool.getSelection();
|
40
|
+
this.editor.dispatch(selection!.duplicateSelectedObjects());
|
41
|
+
},
|
42
|
+
);
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
this.tool.clearSelection();
|
45
|
-
};
|
44
|
+
this.addSubWidget(resizeButton);
|
45
|
+
this.addSubWidget(deleteButton);
|
46
|
+
this.addSubWidget(duplicateButton);
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
const updateDisabled = (disabled: boolean) => {
|
49
|
+
resizeButton.setDisabled(disabled);
|
50
|
+
deleteButton.setDisabled(disabled);
|
51
|
+
duplicateButton.setDisabled(disabled);
|
50
52
|
};
|
53
|
+
updateDisabled(true);
|
51
54
|
|
52
55
|
// Enable/disable actions based on whether items are selected
|
53
56
|
this.editor.notifier.on(EditorEventType.ToolUpdated, toolEvt => {
|
@@ -59,14 +62,16 @@ export class SelectionWidget extends BaseToolWidget {
|
|
59
62
|
const selection = this.tool.getSelection();
|
60
63
|
const hasSelection = selection && selection.region.area > 0;
|
61
64
|
|
62
|
-
|
63
|
-
deleteButton.disabled = resizeButton.disabled;
|
64
|
-
duplicateButton.disabled = resizeButton.disabled;
|
65
|
+
updateDisabled(!hasSelection);
|
65
66
|
}
|
66
67
|
});
|
68
|
+
}
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
protected getTitle(): string {
|
71
|
+
return this.localizationTable.select;
|
72
|
+
}
|
73
|
+
|
74
|
+
protected createIcon(): Element {
|
75
|
+
return makeSelectionIcon();
|
71
76
|
}
|
72
77
|
}
|
package/src/tools/Eraser.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import { PointerEvt } from '../types';
|
2
2
|
import BaseTool from './BaseTool';
|
3
3
|
import Editor from '../Editor';
|
4
|
-
import { Point2 } from '../
|
5
|
-
import LineSegment2 from '../
|
4
|
+
import { Point2 } from '../math/Vec2';
|
5
|
+
import LineSegment2 from '../math/LineSegment2';
|
6
6
|
import Erase from '../commands/Erase';
|
7
7
|
import { ToolType } from './ToolController';
|
8
8
|
import AbstractComponent from '../components/AbstractComponent';
|