js-draw 0.18.2 → 0.20.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/.eslintrc.js +1 -0
- package/CHANGELOG.md +10 -0
- package/dist/bundle.js +2 -2
- package/dist/bundledStyles.js +1 -0
- package/dist/cjs/src/Color4.d.ts +8 -0
- package/dist/cjs/src/Color4.js +67 -0
- package/dist/cjs/src/Editor.d.ts +2 -2
- package/dist/cjs/src/Editor.js +7 -7
- package/dist/cjs/src/SVGLoader.js +77 -12
- package/dist/cjs/src/Viewport.d.ts +2 -0
- package/dist/cjs/src/Viewport.js +6 -2
- package/dist/cjs/src/components/AbstractComponent.d.ts +2 -2
- package/dist/cjs/src/components/AbstractComponent.js +3 -3
- package/dist/cjs/src/components/{ImageBackground.d.ts → BackgroundComponent.d.ts} +23 -3
- package/dist/cjs/src/components/BackgroundComponent.js +309 -0
- package/dist/cjs/src/components/RestylableComponent.d.ts +21 -2
- package/dist/cjs/src/components/Stroke.d.ts +35 -0
- package/dist/cjs/src/components/Stroke.js +37 -3
- package/dist/cjs/src/components/TextComponent.d.ts +27 -17
- package/dist/cjs/src/components/TextComponent.js +23 -1
- package/dist/cjs/src/components/lib.d.ts +4 -3
- package/dist/cjs/src/components/lib.js +2 -2
- package/dist/cjs/src/components/util/StrokeSmoother.js +25 -15
- package/dist/cjs/src/lib.d.ts +30 -0
- package/dist/cjs/src/lib.js +30 -0
- package/dist/cjs/src/localizations/de.js +1 -1
- package/dist/cjs/src/localizations/es.js +1 -1
- package/dist/cjs/src/math/Path.js +1 -1
- package/dist/cjs/src/math/polynomial/QuadraticBezier.d.ts +28 -0
- package/dist/cjs/src/math/polynomial/QuadraticBezier.js +115 -0
- package/dist/cjs/src/math/polynomial/solveQuadratic.d.ts +6 -0
- package/dist/cjs/src/math/polynomial/solveQuadratic.js +36 -0
- package/dist/cjs/src/rendering/RenderingStyle.d.ts +4 -4
- package/dist/cjs/src/rendering/TextRenderingStyle.d.ts +10 -10
- package/dist/cjs/src/rendering/lib.d.ts +2 -0
- package/dist/cjs/src/rendering/renderers/AbstractRenderer.d.ts +2 -2
- package/dist/cjs/src/rendering/renderers/CanvasRenderer.d.ts +2 -2
- package/dist/cjs/src/rendering/renderers/CanvasRenderer.js +5 -3
- package/dist/cjs/src/rendering/renderers/DummyRenderer.d.ts +2 -2
- package/dist/cjs/src/rendering/renderers/SVGRenderer.d.ts +2 -2
- package/dist/cjs/src/rendering/renderers/SVGRenderer.js +15 -6
- package/dist/cjs/src/rendering/renderers/TextOnlyRenderer.d.ts +2 -2
- package/dist/cjs/src/toolbar/IconProvider.d.ts +2 -2
- package/dist/cjs/src/toolbar/localization.d.ts +2 -1
- package/dist/cjs/src/toolbar/localization.js +3 -2
- package/dist/cjs/src/toolbar/widgets/BaseWidget.js +1 -1
- package/dist/cjs/src/toolbar/widgets/DocumentPropertiesWidget.d.ts +5 -0
- package/dist/cjs/src/toolbar/widgets/DocumentPropertiesWidget.js +77 -2
- package/dist/cjs/src/toolbar/widgets/PenToolWidget.js +1 -1
- package/dist/cjs/src/tools/FindTool.js +1 -1
- package/dist/cjs/src/tools/SoundUITool.d.ts +24 -0
- package/dist/cjs/src/tools/SoundUITool.js +164 -0
- package/dist/cjs/src/tools/TextTool.d.ts +2 -2
- package/dist/cjs/src/tools/ToolController.js +6 -1
- package/dist/cjs/src/tools/lib.d.ts +1 -0
- package/dist/cjs/src/tools/lib.js +3 -1
- package/dist/cjs/src/tools/localization.d.ts +3 -0
- package/dist/cjs/src/tools/localization.js +3 -0
- package/dist/mjs/src/Color4.d.ts +8 -0
- package/dist/mjs/src/Color4.mjs +64 -0
- package/dist/mjs/src/Editor.d.ts +2 -2
- package/dist/mjs/src/Editor.mjs +6 -6
- package/dist/mjs/src/SVGLoader.mjs +76 -11
- package/dist/mjs/src/Viewport.d.ts +2 -0
- package/dist/mjs/src/Viewport.mjs +6 -2
- package/dist/mjs/src/components/AbstractComponent.d.ts +2 -2
- package/dist/mjs/src/components/AbstractComponent.mjs +3 -3
- package/dist/mjs/src/components/{ImageBackground.d.ts → BackgroundComponent.d.ts} +23 -3
- package/dist/mjs/src/components/BackgroundComponent.mjs +279 -0
- package/dist/mjs/src/components/RestylableComponent.d.ts +21 -2
- package/dist/mjs/src/components/Stroke.d.ts +35 -0
- package/dist/mjs/src/components/Stroke.mjs +37 -3
- package/dist/mjs/src/components/TextComponent.d.ts +27 -17
- package/dist/mjs/src/components/TextComponent.mjs +23 -1
- package/dist/mjs/src/components/lib.d.ts +4 -3
- package/dist/mjs/src/components/lib.mjs +2 -2
- package/dist/mjs/src/components/util/StrokeSmoother.mjs +25 -15
- package/dist/mjs/src/lib.d.ts +30 -0
- package/dist/mjs/src/lib.mjs +30 -0
- package/dist/mjs/src/localizations/de.mjs +1 -1
- package/dist/mjs/src/localizations/es.mjs +1 -1
- package/dist/mjs/src/math/Path.mjs +1 -1
- package/dist/mjs/src/math/polynomial/QuadraticBezier.d.ts +28 -0
- package/dist/mjs/src/math/polynomial/QuadraticBezier.mjs +109 -0
- package/dist/mjs/src/math/polynomial/solveQuadratic.d.ts +6 -0
- package/dist/mjs/src/math/polynomial/solveQuadratic.mjs +34 -0
- package/dist/mjs/src/rendering/RenderingStyle.d.ts +4 -4
- package/dist/mjs/src/rendering/TextRenderingStyle.d.ts +10 -10
- package/dist/mjs/src/rendering/lib.d.ts +2 -0
- package/dist/mjs/src/rendering/renderers/AbstractRenderer.d.ts +2 -2
- package/dist/mjs/src/rendering/renderers/CanvasRenderer.d.ts +2 -2
- package/dist/mjs/src/rendering/renderers/CanvasRenderer.mjs +5 -3
- package/dist/mjs/src/rendering/renderers/DummyRenderer.d.ts +2 -2
- package/dist/mjs/src/rendering/renderers/SVGRenderer.d.ts +2 -2
- package/dist/mjs/src/rendering/renderers/SVGRenderer.mjs +15 -6
- package/dist/mjs/src/rendering/renderers/TextOnlyRenderer.d.ts +2 -2
- package/dist/mjs/src/toolbar/IconProvider.d.ts +2 -2
- package/dist/mjs/src/toolbar/localization.d.ts +2 -1
- package/dist/mjs/src/toolbar/localization.mjs +3 -2
- package/dist/mjs/src/toolbar/widgets/BaseWidget.mjs +1 -1
- package/dist/mjs/src/toolbar/widgets/DocumentPropertiesWidget.d.ts +5 -0
- package/dist/mjs/src/toolbar/widgets/DocumentPropertiesWidget.mjs +54 -2
- package/dist/mjs/src/toolbar/widgets/PenToolWidget.mjs +1 -1
- package/dist/mjs/src/tools/FindTool.mjs +1 -1
- package/dist/mjs/src/tools/SoundUITool.d.ts +24 -0
- package/dist/mjs/src/tools/SoundUITool.mjs +158 -0
- package/dist/mjs/src/tools/TextTool.d.ts +2 -2
- package/dist/mjs/src/tools/ToolController.mjs +6 -1
- package/dist/mjs/src/tools/lib.d.ts +1 -0
- package/dist/mjs/src/tools/lib.mjs +1 -0
- package/dist/mjs/src/tools/localization.d.ts +3 -0
- package/dist/mjs/src/tools/localization.mjs +3 -0
- package/jest.config.js +1 -1
- package/package.json +19 -17
- package/src/Editor.css +2 -2
- package/src/tools/SoundUITool.css +15 -0
- package/src/tools/tools.css +4 -0
- package/dist/cjs/src/components/ImageBackground.js +0 -146
- package/dist/mjs/src/components/ImageBackground.mjs +0 -139
- package/src/Color4.test.ts +0 -40
- package/src/Color4.ts +0 -236
- package/src/Editor.loadFrom.test.ts +0 -24
- package/src/Editor.toSVG.test.ts +0 -111
- package/src/Editor.ts +0 -1122
- package/src/EditorImage.test.ts +0 -120
- package/src/EditorImage.ts +0 -603
- package/src/EventDispatcher.test.ts +0 -123
- package/src/EventDispatcher.ts +0 -71
- package/src/Pointer.ts +0 -127
- package/src/SVGLoader.test.ts +0 -114
- package/src/SVGLoader.ts +0 -511
- package/src/UndoRedoHistory.test.ts +0 -33
- package/src/UndoRedoHistory.ts +0 -102
- package/src/Viewport.ts +0 -319
- package/src/bundle/bundled.ts +0 -7
- package/src/commands/Command.ts +0 -45
- package/src/commands/Duplicate.ts +0 -48
- package/src/commands/Erase.ts +0 -74
- package/src/commands/SerializableCommand.ts +0 -49
- package/src/commands/UnresolvedCommand.ts +0 -37
- package/src/commands/invertCommand.ts +0 -51
- package/src/commands/lib.ts +0 -16
- package/src/commands/localization.ts +0 -47
- package/src/commands/uniteCommands.test.ts +0 -23
- package/src/commands/uniteCommands.ts +0 -135
- package/src/components/AbstractComponent.transformBy.test.ts +0 -22
- package/src/components/AbstractComponent.ts +0 -364
- package/src/components/ImageBackground.test.ts +0 -35
- package/src/components/ImageBackground.ts +0 -176
- package/src/components/ImageComponent.ts +0 -171
- package/src/components/RestylableComponent.ts +0 -142
- package/src/components/SVGGlobalAttributesObject.ts +0 -81
- package/src/components/Stroke.test.ts +0 -139
- package/src/components/Stroke.ts +0 -245
- package/src/components/TextComponent.test.ts +0 -99
- package/src/components/TextComponent.ts +0 -315
- package/src/components/UnknownSVGObject.test.ts +0 -10
- package/src/components/UnknownSVGObject.ts +0 -60
- package/src/components/builders/ArrowBuilder.ts +0 -107
- package/src/components/builders/FreehandLineBuilder.ts +0 -212
- package/src/components/builders/LineBuilder.ts +0 -77
- package/src/components/builders/PressureSensitiveFreehandLineBuilder.ts +0 -454
- package/src/components/builders/RectangleBuilder.ts +0 -74
- package/src/components/builders/types.ts +0 -15
- package/src/components/lib.ts +0 -25
- package/src/components/localization.ts +0 -22
- package/src/components/util/StrokeSmoother.ts +0 -293
- package/src/components/util/describeComponentList.ts +0 -18
- package/src/lib.ts +0 -37
- package/src/localization.ts +0 -34
- package/src/localizations/de.ts +0 -98
- package/src/localizations/en.ts +0 -8
- package/src/localizations/es.ts +0 -74
- package/src/localizations/getLocalizationTable.test.ts +0 -27
- package/src/localizations/getLocalizationTable.ts +0 -55
- package/src/math/LineSegment2.test.ts +0 -99
- package/src/math/LineSegment2.ts +0 -160
- package/src/math/Mat33.test.ts +0 -244
- package/src/math/Mat33.ts +0 -437
- package/src/math/Path.fromString.test.ts +0 -223
- package/src/math/Path.test.ts +0 -198
- package/src/math/Path.toString.test.ts +0 -77
- package/src/math/Path.ts +0 -790
- package/src/math/Rect2.test.ts +0 -204
- package/src/math/Rect2.ts +0 -315
- package/src/math/Triangle.ts +0 -29
- package/src/math/Vec2.test.ts +0 -30
- package/src/math/Vec2.ts +0 -18
- package/src/math/Vec3.test.ts +0 -44
- package/src/math/Vec3.ts +0 -218
- package/src/math/lib.ts +0 -15
- package/src/math/rounding.test.ts +0 -65
- package/src/math/rounding.ts +0 -156
- package/src/rendering/Display.ts +0 -249
- package/src/rendering/RenderingStyle.test.ts +0 -68
- package/src/rendering/RenderingStyle.ts +0 -55
- package/src/rendering/TextRenderingStyle.ts +0 -45
- package/src/rendering/caching/CacheRecord.test.ts +0 -49
- package/src/rendering/caching/CacheRecord.ts +0 -77
- package/src/rendering/caching/CacheRecordManager.ts +0 -71
- package/src/rendering/caching/RenderingCache.test.ts +0 -44
- package/src/rendering/caching/RenderingCache.ts +0 -66
- package/src/rendering/caching/RenderingCacheNode.ts +0 -405
- package/src/rendering/caching/testUtils.ts +0 -35
- package/src/rendering/caching/types.ts +0 -34
- package/src/rendering/lib.ts +0 -6
- package/src/rendering/localization.ts +0 -20
- package/src/rendering/renderers/AbstractRenderer.ts +0 -222
- package/src/rendering/renderers/CanvasRenderer.ts +0 -296
- package/src/rendering/renderers/DummyRenderer.test.ts +0 -42
- package/src/rendering/renderers/DummyRenderer.ts +0 -136
- package/src/rendering/renderers/SVGRenderer.ts +0 -354
- package/src/rendering/renderers/TextOnlyRenderer.ts +0 -70
- package/src/testing/beforeEachFile.ts +0 -8
- package/src/testing/createEditor.ts +0 -11
- package/src/testing/global.d.ts +0 -17
- package/src/testing/lib.ts +0 -3
- package/src/testing/loadExpectExtensions.ts +0 -25
- package/src/testing/sendPenEvent.ts +0 -31
- package/src/testing/sendTouchEvent.ts +0 -78
- package/src/toolbar/HTMLToolbar.ts +0 -492
- package/src/toolbar/IconProvider.ts +0 -736
- package/src/toolbar/lib.ts +0 -4
- package/src/toolbar/localization.ts +0 -106
- package/src/toolbar/makeColorInput.ts +0 -145
- package/src/toolbar/types.ts +0 -5
- package/src/toolbar/widgets/ActionButtonWidget.ts +0 -39
- package/src/toolbar/widgets/BaseToolWidget.ts +0 -56
- package/src/toolbar/widgets/BaseWidget.ts +0 -377
- package/src/toolbar/widgets/DocumentPropertiesWidget.ts +0 -167
- package/src/toolbar/widgets/EraserToolWidget.ts +0 -85
- package/src/toolbar/widgets/HandToolWidget.ts +0 -250
- package/src/toolbar/widgets/InsertImageWidget.ts +0 -223
- package/src/toolbar/widgets/OverflowWidget.ts +0 -92
- package/src/toolbar/widgets/PenToolWidget.ts +0 -288
- package/src/toolbar/widgets/SelectionToolWidget.ts +0 -190
- package/src/toolbar/widgets/TextToolWidget.ts +0 -145
- package/src/toolbar/widgets/lib.ts +0 -13
- package/src/tools/BaseTool.ts +0 -76
- package/src/tools/Eraser.test.ts +0 -103
- package/src/tools/Eraser.ts +0 -139
- package/src/tools/FindTool.ts +0 -152
- package/src/tools/PanZoom.test.ts +0 -310
- package/src/tools/PanZoom.ts +0 -520
- package/src/tools/PasteHandler.ts +0 -95
- package/src/tools/Pen.test.ts +0 -194
- package/src/tools/Pen.ts +0 -226
- package/src/tools/PipetteTool.ts +0 -55
- package/src/tools/SelectionTool/SelectAllShortcutHandler.ts +0 -28
- package/src/tools/SelectionTool/Selection.ts +0 -607
- package/src/tools/SelectionTool/SelectionHandle.ts +0 -108
- package/src/tools/SelectionTool/SelectionTool.test.ts +0 -261
- package/src/tools/SelectionTool/SelectionTool.ts +0 -480
- package/src/tools/SelectionTool/TransformMode.ts +0 -114
- package/src/tools/SelectionTool/types.ts +0 -11
- package/src/tools/TextTool.ts +0 -326
- package/src/tools/ToolController.ts +0 -178
- package/src/tools/ToolEnabledGroup.ts +0 -14
- package/src/tools/ToolSwitcherShortcut.ts +0 -39
- package/src/tools/ToolbarShortcutHandler.ts +0 -34
- package/src/tools/UndoRedoShortcut.test.ts +0 -56
- package/src/tools/UndoRedoShortcut.ts +0 -25
- package/src/tools/lib.ts +0 -21
- package/src/tools/localization.ts +0 -66
- package/src/types.ts +0 -234
- package/src/util/assertions.ts +0 -55
- package/src/util/fileToBase64.ts +0 -18
- package/src/util/untilNextAnimationFrame.ts +0 -9
- package/src/util/waitForTimeout.ts +0 -9
@@ -1,6 +1,6 @@
|
|
1
1
|
import Color4 from '../Color4';
|
2
2
|
import { ComponentBuilderFactory } from '../components/builders/types';
|
3
|
-
import
|
3
|
+
import TextRenderingStyle from '../rendering/TextRenderingStyle';
|
4
4
|
import Pen from '../tools/Pen';
|
5
5
|
export type IconType = HTMLImageElement | SVGElement;
|
6
6
|
/**
|
@@ -47,7 +47,7 @@ export default class IconProvider {
|
|
47
47
|
makeZoomIcon(): IconType;
|
48
48
|
makeRotationLockIcon(): IconType;
|
49
49
|
makeInsertImageIcon(): IconType;
|
50
|
-
makeTextIcon(textStyle:
|
50
|
+
makeTextIcon(textStyle: TextRenderingStyle): IconType;
|
51
51
|
makePenIcon(strokeSize: number, color: string | Color4, rounded?: boolean): IconType;
|
52
52
|
makeIconFromFactory(pen: Pen, factory: ComponentBuilderFactory): IconType;
|
53
53
|
makePipetteIcon(color?: Color4): IconType;
|
@@ -14,7 +14,7 @@ export interface ToolbarLocalization {
|
|
14
14
|
submit: string;
|
15
15
|
freehandPen: string;
|
16
16
|
pressureSensitiveFreehandPen: string;
|
17
|
-
|
17
|
+
selectPenType: string;
|
18
18
|
colorLabel: string;
|
19
19
|
pen: string;
|
20
20
|
eraser: string;
|
@@ -37,6 +37,7 @@ export interface ToolbarLocalization {
|
|
37
37
|
backgroundColor: string;
|
38
38
|
imageWidthOption: string;
|
39
39
|
imageHeightOption: string;
|
40
|
+
useGridOption: string;
|
40
41
|
toggleOverflow: string;
|
41
42
|
errorImageHasZeroSize: string;
|
42
43
|
dropdownShown: (toolName: string) => string;
|
@@ -23,14 +23,15 @@ exports.defaultToolbarLocalization = {
|
|
23
23
|
duplicateSelection: 'Duplicate selection',
|
24
24
|
undo: 'Undo',
|
25
25
|
redo: 'Redo',
|
26
|
-
|
26
|
+
selectPenType: 'Pen type: ',
|
27
27
|
pickColorFromScreen: 'Pick color from screen',
|
28
28
|
clickToPickColorAnnouncement: 'Click on the screen to pick a color',
|
29
29
|
selectionToolKeyboardShortcuts: 'Selection tool: Use arrow keys to move selected items, lowercase/uppercase ‘i’ and ‘o’ to resize.',
|
30
|
-
documentProperties: '
|
30
|
+
documentProperties: 'Page',
|
31
31
|
backgroundColor: 'Background Color: ',
|
32
32
|
imageWidthOption: 'Width: ',
|
33
33
|
imageHeightOption: 'Height: ',
|
34
|
+
useGridOption: 'Grid: ',
|
34
35
|
toggleOverflow: 'More',
|
35
36
|
touchPanning: 'Touchscreen panning',
|
36
37
|
freehandPen: 'Freehand',
|
@@ -127,7 +127,7 @@ class BaseWidget {
|
|
127
127
|
}
|
128
128
|
// Add a listener that is triggered when a key is pressed.
|
129
129
|
// Listeners will fire regardless of whether this widget is selected and require that
|
130
|
-
// {@link
|
130
|
+
// {@link Editor.toolController} to have an enabled {@link ToolbarShortcutHandler} tool.
|
131
131
|
onKeyPress(_event) {
|
132
132
|
return false;
|
133
133
|
}
|
@@ -12,6 +12,11 @@ export default class DocumentPropertiesWidget extends BaseWidget {
|
|
12
12
|
private updateDropdown;
|
13
13
|
private setBackgroundColor;
|
14
14
|
private getBackgroundColor;
|
15
|
+
private removeBackgroundComponents;
|
16
|
+
/** Replace existing background components with a background of the given type. */
|
17
|
+
private setBackgroundType;
|
18
|
+
/** Returns the type of the topmost background component */
|
19
|
+
private getBackgroundType;
|
15
20
|
private updateImportExportRectSize;
|
16
21
|
private static idCounter;
|
17
22
|
protected fillDropdown(dropdown: HTMLElement): boolean;
|
@@ -1,8 +1,34 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
27
|
};
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
+
const Erase_1 = __importDefault(require("../../commands/Erase"));
|
30
|
+
const uniteCommands_1 = __importDefault(require("../../commands/uniteCommands"));
|
31
|
+
const BackgroundComponent_1 = __importStar(require("../../components/BackgroundComponent"));
|
6
32
|
const EditorImage_1 = require("../../EditorImage");
|
7
33
|
const Rect2_1 = __importDefault(require("../../math/Rect2"));
|
8
34
|
const types_1 = require("../../types");
|
@@ -11,7 +37,7 @@ const makeColorInput_1 = __importDefault(require("../makeColorInput"));
|
|
11
37
|
const BaseWidget_1 = __importDefault(require("./BaseWidget"));
|
12
38
|
class DocumentPropertiesWidget extends BaseWidget_1.default {
|
13
39
|
constructor(editor, localizationTable) {
|
14
|
-
super(editor, '
|
40
|
+
super(editor, 'document-properties-widget', localizationTable);
|
15
41
|
this.updateDropdownContent = () => { };
|
16
42
|
this.dropdownUpdateQueued = false;
|
17
43
|
// Make it possible to open the dropdown, even if this widget isn't selected.
|
@@ -51,6 +77,33 @@ class DocumentPropertiesWidget extends BaseWidget_1.default {
|
|
51
77
|
getBackgroundColor() {
|
52
78
|
return this.editor.estimateBackgroundColor();
|
53
79
|
}
|
80
|
+
removeBackgroundComponents() {
|
81
|
+
const previousBackgrounds = [];
|
82
|
+
for (const component of this.editor.image.getBackgroundComponents()) {
|
83
|
+
if (component instanceof BackgroundComponent_1.default) {
|
84
|
+
previousBackgrounds.push(component);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
return new Erase_1.default(previousBackgrounds);
|
88
|
+
}
|
89
|
+
/** Replace existing background components with a background of the given type. */
|
90
|
+
setBackgroundType(backgroundType) {
|
91
|
+
const prevBackgroundColor = this.editor.estimateBackgroundColor();
|
92
|
+
const newBackground = new BackgroundComponent_1.default(backgroundType, prevBackgroundColor);
|
93
|
+
const addBackgroundCommand = this.editor.image.addElement(newBackground);
|
94
|
+
return (0, uniteCommands_1.default)([this.removeBackgroundComponents(), addBackgroundCommand]);
|
95
|
+
}
|
96
|
+
/** Returns the type of the topmost background component */
|
97
|
+
getBackgroundType() {
|
98
|
+
const backgroundComponents = this.editor.image.getBackgroundComponents();
|
99
|
+
for (let i = backgroundComponents.length - 1; i >= 0; i--) {
|
100
|
+
const component = backgroundComponents[i];
|
101
|
+
if (component instanceof BackgroundComponent_1.default) {
|
102
|
+
return component.getBackgroundType();
|
103
|
+
}
|
104
|
+
}
|
105
|
+
return BackgroundComponent_1.BackgroundType.None;
|
106
|
+
}
|
54
107
|
updateImportExportRectSize(size) {
|
55
108
|
const filterDimension = (dim) => {
|
56
109
|
if (dim !== undefined && (!isFinite(dim) || dim <= 0)) {
|
@@ -79,6 +132,27 @@ class DocumentPropertiesWidget extends BaseWidget_1.default {
|
|
79
132
|
colorInput.id = `${HTMLToolbar_1.toolbarCSSPrefix}docPropertiesColorInput-${DocumentPropertiesWidget.idCounter++}`;
|
80
133
|
backgroundColorLabel.htmlFor = colorInput.id;
|
81
134
|
backgroundColorRow.replaceChildren(backgroundColorLabel, backgroundColorInputContainer);
|
135
|
+
const useGridRow = document.createElement('div');
|
136
|
+
const useGridLabel = document.createElement('label');
|
137
|
+
const useGridCheckbox = document.createElement('input');
|
138
|
+
useGridCheckbox.id = `${HTMLToolbar_1.toolbarCSSPrefix}docPropertiesUseGridCheckbox-${DocumentPropertiesWidget.idCounter++}`;
|
139
|
+
useGridLabel.htmlFor = useGridCheckbox.id;
|
140
|
+
useGridCheckbox.type = 'checkbox';
|
141
|
+
useGridLabel.innerText = this.localizationTable.useGridOption;
|
142
|
+
useGridCheckbox.oninput = () => {
|
143
|
+
const prevBackgroundType = this.getBackgroundType();
|
144
|
+
const wasGrid = prevBackgroundType === BackgroundComponent_1.BackgroundType.Grid;
|
145
|
+
if (wasGrid === useGridCheckbox.checked) {
|
146
|
+
// Already the requested background type.
|
147
|
+
return;
|
148
|
+
}
|
149
|
+
let newBackgroundType = BackgroundComponent_1.BackgroundType.SolidColor;
|
150
|
+
if (useGridCheckbox.checked) {
|
151
|
+
newBackgroundType = BackgroundComponent_1.BackgroundType.Grid;
|
152
|
+
}
|
153
|
+
this.editor.dispatch(this.setBackgroundType(newBackgroundType));
|
154
|
+
};
|
155
|
+
useGridRow.replaceChildren(useGridLabel, useGridCheckbox);
|
82
156
|
const addDimensionRow = (labelContent, onChange) => {
|
83
157
|
const row = document.createElement('div');
|
84
158
|
const label = document.createElement('label');
|
@@ -115,9 +189,10 @@ class DocumentPropertiesWidget extends BaseWidget_1.default {
|
|
115
189
|
const importExportRect = this.editor.getImportExportRect();
|
116
190
|
imageWidthRow.setValue(importExportRect.width);
|
117
191
|
imageHeightRow.setValue(importExportRect.height);
|
192
|
+
useGridCheckbox.checked = this.getBackgroundType() === BackgroundComponent_1.BackgroundType.Grid;
|
118
193
|
};
|
119
194
|
this.updateDropdownContent();
|
120
|
-
container.replaceChildren(backgroundColorRow, imageWidthRow.element, imageHeightRow.element);
|
195
|
+
container.replaceChildren(backgroundColorRow, useGridRow, imageWidthRow.element, imageHeightRow.element);
|
121
196
|
dropdown.replaceChildren(container);
|
122
197
|
return true;
|
123
198
|
}
|
@@ -115,7 +115,7 @@ class PenToolWidget extends BaseToolWidget_1.default {
|
|
115
115
|
objectTypeSelect.id = `${HTMLToolbar_1.toolbarCSSPrefix}penBuilderSelect${PenToolWidget.idCounter++}`;
|
116
116
|
thicknessLabel.innerText = this.localizationTable.thicknessLabel;
|
117
117
|
thicknessLabel.setAttribute('for', thicknessInput.id);
|
118
|
-
objectSelectLabel.innerText = this.localizationTable.
|
118
|
+
objectSelectLabel.innerText = this.localizationTable.selectPenType;
|
119
119
|
objectSelectLabel.setAttribute('for', objectTypeSelect.id);
|
120
120
|
// Use a logarithmic scale for thicknessInput (finer control over thinner strokewidths.)
|
121
121
|
const inverseThicknessInputFn = (t) => Math.log10(t);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
"use strict";
|
2
|
-
// Displays a find dialog that allows the user to search for and focus text.
|
2
|
+
// Displays a find dialog that allows the user to search for and focus text.
|
3
3
|
//
|
4
4
|
// @packageDocumentation
|
5
5
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import Editor from '../Editor';
|
2
|
+
import { PointerEvt } from '../types';
|
3
|
+
import BaseTool from './BaseTool';
|
4
|
+
/**
|
5
|
+
* This tool, when enabled, plays a sound representing the color of the portion of the display
|
6
|
+
* currently under the cursor. This tool adds a button that can be navigated to with the tab key
|
7
|
+
* that enables/disables the tool.
|
8
|
+
*
|
9
|
+
* This allows the user to explore the content of the display without a working screen.
|
10
|
+
*/
|
11
|
+
export default class SoundUITool extends BaseTool {
|
12
|
+
private editor;
|
13
|
+
private soundFeedback;
|
14
|
+
private toggleButton;
|
15
|
+
private toggleButtonContainer;
|
16
|
+
constructor(editor: Editor, description: string);
|
17
|
+
private updateToggleButtonText;
|
18
|
+
setEnabled(enabled: boolean): void;
|
19
|
+
private lastPointerPos;
|
20
|
+
onPointerDown({ current, allPointers }: PointerEvt): boolean;
|
21
|
+
onPointerMove({ current }: PointerEvt): void;
|
22
|
+
onPointerUp(_event: PointerEvt): void;
|
23
|
+
onGestureCancel(): void;
|
24
|
+
}
|
@@ -0,0 +1,164 @@
|
|
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
|
+
const Color4_1 = __importDefault(require("../Color4"));
|
7
|
+
const LineSegment2_1 = __importDefault(require("../math/LineSegment2"));
|
8
|
+
const BaseTool_1 = __importDefault(require("./BaseTool"));
|
9
|
+
class SoundFeedback {
|
10
|
+
constructor() {
|
11
|
+
this.closed = false;
|
12
|
+
// No AudioContext? Exit!
|
13
|
+
if (!window.AudioContext) {
|
14
|
+
console.warn('Accessibility sound UI: Unable to open AudioContext.');
|
15
|
+
this.closed = true;
|
16
|
+
return;
|
17
|
+
}
|
18
|
+
this.ctx = new AudioContext();
|
19
|
+
// Color oscillator and gain
|
20
|
+
this.colorOscHue = this.ctx.createOscillator();
|
21
|
+
this.colorOscValue = this.ctx.createOscillator();
|
22
|
+
this.colorOscSaturation = this.ctx.createOscillator();
|
23
|
+
this.colorOscHue.type = 'triangle';
|
24
|
+
this.colorOscSaturation.type = 'sine';
|
25
|
+
this.colorOscValue.type = 'sawtooth';
|
26
|
+
this.valueGain = this.ctx.createGain();
|
27
|
+
this.colorOscValue.connect(this.valueGain);
|
28
|
+
this.valueGain.gain.setValueAtTime(0.18, this.ctx.currentTime);
|
29
|
+
this.colorGain = this.ctx.createGain();
|
30
|
+
this.colorOscHue.connect(this.colorGain);
|
31
|
+
this.valueGain.connect(this.colorGain);
|
32
|
+
this.colorOscSaturation.connect(this.colorGain);
|
33
|
+
this.colorGain.connect(this.ctx.destination);
|
34
|
+
// Boundary oscillator and gain
|
35
|
+
this.boundaryGain = this.ctx.createGain();
|
36
|
+
this.boundaryOsc = this.ctx.createOscillator();
|
37
|
+
this.boundaryOsc.type = 'sawtooth';
|
38
|
+
this.boundaryGain.gain.setValueAtTime(0, this.ctx.currentTime);
|
39
|
+
this.boundaryOsc.connect(this.boundaryGain);
|
40
|
+
this.boundaryGain.connect(this.ctx.destination);
|
41
|
+
// Prepare for the first announcement/feedback.
|
42
|
+
this.colorOscHue.start();
|
43
|
+
this.colorOscSaturation.start();
|
44
|
+
this.colorOscValue.start();
|
45
|
+
this.boundaryOsc.start();
|
46
|
+
this.pause();
|
47
|
+
}
|
48
|
+
pause() {
|
49
|
+
if (this.closed)
|
50
|
+
return;
|
51
|
+
this.colorGain.gain.setValueAtTime(0, this.ctx.currentTime);
|
52
|
+
void this.ctx.suspend();
|
53
|
+
}
|
54
|
+
play() {
|
55
|
+
if (this.closed)
|
56
|
+
return;
|
57
|
+
void this.ctx.resume();
|
58
|
+
}
|
59
|
+
setColor(color) {
|
60
|
+
const hsv = color.asHSV();
|
61
|
+
// Choose frequencies that roughly correspond to hue, saturation, and value.
|
62
|
+
const hueFrequency = (-Math.cos(hsv.x / 2)) * 220 + 440;
|
63
|
+
const saturationFrequency = hsv.y * 440 + 220;
|
64
|
+
const valueFrequency = (hsv.z + 0.1) * 440;
|
65
|
+
// Sigmoid with maximum 0.25 * alpha.
|
66
|
+
// Louder for greater value.
|
67
|
+
const gain = 0.25 * Math.min(1, color.a) / (1 + Math.exp(-(hsv.z - 0.5) * 3));
|
68
|
+
this.colorOscHue.frequency.setValueAtTime(hueFrequency, this.ctx.currentTime);
|
69
|
+
this.colorOscSaturation.frequency.setValueAtTime(saturationFrequency, this.ctx.currentTime);
|
70
|
+
this.colorOscValue.frequency.setValueAtTime(valueFrequency, this.ctx.currentTime);
|
71
|
+
this.valueGain.gain.setValueAtTime((1 - hsv.z) * 0.4, this.ctx.currentTime);
|
72
|
+
this.colorGain.gain.setValueAtTime(gain, this.ctx.currentTime);
|
73
|
+
}
|
74
|
+
announceBoundaryCross(boundaryCrossCount) {
|
75
|
+
this.boundaryGain.gain.cancelScheduledValues(this.ctx.currentTime);
|
76
|
+
this.boundaryGain.gain.setValueAtTime(0, this.ctx.currentTime);
|
77
|
+
this.boundaryGain.gain.linearRampToValueAtTime(0.018, this.ctx.currentTime + 0.1);
|
78
|
+
this.boundaryOsc.frequency.setValueAtTime(440 + Math.atan(boundaryCrossCount / 2) * 100, this.ctx.currentTime);
|
79
|
+
this.boundaryGain.gain.linearRampToValueAtTime(0, this.ctx.currentTime + 0.25);
|
80
|
+
}
|
81
|
+
close() {
|
82
|
+
this.ctx.close();
|
83
|
+
this.closed = true;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
/**
|
87
|
+
* This tool, when enabled, plays a sound representing the color of the portion of the display
|
88
|
+
* currently under the cursor. This tool adds a button that can be navigated to with the tab key
|
89
|
+
* that enables/disables the tool.
|
90
|
+
*
|
91
|
+
* This allows the user to explore the content of the display without a working screen.
|
92
|
+
*/
|
93
|
+
class SoundUITool extends BaseTool_1.default {
|
94
|
+
constructor(editor, description) {
|
95
|
+
super(editor.notifier, description);
|
96
|
+
this.editor = editor;
|
97
|
+
this.soundFeedback = null;
|
98
|
+
// Create a screen-reader-usable method of toggling the tool:
|
99
|
+
this.toggleButtonContainer = document.createElement('div');
|
100
|
+
this.toggleButtonContainer.classList.add('js-draw-sound-ui-toggle');
|
101
|
+
this.toggleButton = document.createElement('button');
|
102
|
+
this.toggleButton.onclick = () => {
|
103
|
+
this.setEnabled(!this.isEnabled());
|
104
|
+
};
|
105
|
+
this.toggleButtonContainer.appendChild(this.toggleButton);
|
106
|
+
this.updateToggleButtonText();
|
107
|
+
editor.createHTMLOverlay(this.toggleButtonContainer);
|
108
|
+
}
|
109
|
+
updateToggleButtonText() {
|
110
|
+
const containerEnabledClass = 'sound-ui-tool-enabled';
|
111
|
+
if (this.isEnabled()) {
|
112
|
+
this.toggleButton.innerText = this.editor.localization.disableAccessibilityExploreTool;
|
113
|
+
this.toggleButtonContainer.classList.add(containerEnabledClass);
|
114
|
+
}
|
115
|
+
else {
|
116
|
+
this.toggleButton.innerText = this.editor.localization.enableAccessibilityExploreTool;
|
117
|
+
this.toggleButtonContainer.classList.remove(containerEnabledClass);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
setEnabled(enabled) {
|
121
|
+
var _a;
|
122
|
+
super.setEnabled(enabled);
|
123
|
+
if (!enabled) {
|
124
|
+
(_a = this.soundFeedback) === null || _a === void 0 ? void 0 : _a.close();
|
125
|
+
this.soundFeedback = null;
|
126
|
+
}
|
127
|
+
this.updateToggleButtonText();
|
128
|
+
}
|
129
|
+
onPointerDown({ current, allPointers }) {
|
130
|
+
var _a, _b, _c;
|
131
|
+
if (!this.soundFeedback) {
|
132
|
+
this.soundFeedback = new SoundFeedback();
|
133
|
+
}
|
134
|
+
// Allow two-finger gestures to move the screen.
|
135
|
+
if (allPointers.length >= 2) {
|
136
|
+
return false;
|
137
|
+
}
|
138
|
+
// Accept multiple cursors -- some screen readers require multiple (touch) pointers to interact with
|
139
|
+
// an image instead of using the built-in navigation features.
|
140
|
+
(_a = this.soundFeedback) === null || _a === void 0 ? void 0 : _a.play();
|
141
|
+
(_b = this.soundFeedback) === null || _b === void 0 ? void 0 : _b.setColor((_c = this.editor.display.getColorAt(current.screenPos)) !== null && _c !== void 0 ? _c : Color4_1.default.black);
|
142
|
+
this.lastPointerPos = current.canvasPos;
|
143
|
+
return true;
|
144
|
+
}
|
145
|
+
onPointerMove({ current }) {
|
146
|
+
var _a, _b, _c;
|
147
|
+
(_a = this.soundFeedback) === null || _a === void 0 ? void 0 : _a.setColor((_b = this.editor.display.getColorAt(current.screenPos)) !== null && _b !== void 0 ? _b : Color4_1.default.black);
|
148
|
+
const pointerMotionLine = new LineSegment2_1.default(this.lastPointerPos, current.canvasPos);
|
149
|
+
const collisions = this.editor.image.getElementsIntersectingRegion(pointerMotionLine.bbox).filter(component => component.intersects(pointerMotionLine));
|
150
|
+
this.lastPointerPos = current.canvasPos;
|
151
|
+
if (collisions.length > 0) {
|
152
|
+
(_c = this.soundFeedback) === null || _c === void 0 ? void 0 : _c.announceBoundaryCross(collisions.length);
|
153
|
+
}
|
154
|
+
}
|
155
|
+
onPointerUp(_event) {
|
156
|
+
var _a;
|
157
|
+
(_a = this.soundFeedback) === null || _a === void 0 ? void 0 : _a.pause();
|
158
|
+
}
|
159
|
+
onGestureCancel() {
|
160
|
+
var _a;
|
161
|
+
(_a = this.soundFeedback) === null || _a === void 0 ? void 0 : _a.pause();
|
162
|
+
}
|
163
|
+
}
|
164
|
+
exports.default = SoundUITool;
|
@@ -3,7 +3,7 @@ import Editor from '../Editor';
|
|
3
3
|
import { PointerEvt } from '../types';
|
4
4
|
import BaseTool from './BaseTool';
|
5
5
|
import { ToolLocalization } from './localization';
|
6
|
-
import
|
6
|
+
import TextRenderingStyle from '../rendering/TextRenderingStyle';
|
7
7
|
export default class TextTool extends BaseTool {
|
8
8
|
private editor;
|
9
9
|
private localizationTable;
|
@@ -28,6 +28,6 @@ export default class TextTool extends BaseTool {
|
|
28
28
|
setFontFamily(fontFamily: string): void;
|
29
29
|
setColor(color: Color4): void;
|
30
30
|
setFontSize(size: number): void;
|
31
|
-
getTextStyle():
|
31
|
+
getTextStyle(): TextRenderingStyle;
|
32
32
|
private setTextStyle;
|
33
33
|
}
|
@@ -42,6 +42,7 @@ const ToolbarShortcutHandler_1 = __importDefault(require("./ToolbarShortcutHandl
|
|
42
42
|
const PressureSensitiveFreehandLineBuilder_1 = require("../components/builders/PressureSensitiveFreehandLineBuilder");
|
43
43
|
const FindTool_1 = __importDefault(require("./FindTool"));
|
44
44
|
const SelectAllShortcutHandler_1 = __importDefault(require("./SelectionTool/SelectAllShortcutHandler"));
|
45
|
+
const SoundUITool_1 = __importDefault(require("./SoundUITool"));
|
45
46
|
class ToolController {
|
46
47
|
/** @internal */
|
47
48
|
constructor(editor, localization) {
|
@@ -60,10 +61,14 @@ class ToolController {
|
|
60
61
|
new Eraser_1.default(editor, localization.eraserTool),
|
61
62
|
new SelectionTool_1.default(editor, localization.selectionTool),
|
62
63
|
new TextTool_1.default(editor, localization.textTool, localization),
|
63
|
-
new PanZoom_1.default(editor, PanZoom_1.PanZoomMode.SinglePointerGestures, localization.anyDevicePanning)
|
64
|
+
new PanZoom_1.default(editor, PanZoom_1.PanZoomMode.SinglePointerGestures, localization.anyDevicePanning),
|
64
65
|
];
|
66
|
+
// Accessibility tools
|
67
|
+
const soundExplorer = new SoundUITool_1.default(editor, localization.soundExplorer);
|
68
|
+
soundExplorer.setEnabled(false);
|
65
69
|
this.tools = [
|
66
70
|
new PipetteTool_1.default(editor, localization.pipetteTool),
|
71
|
+
soundExplorer,
|
67
72
|
panZoomTool,
|
68
73
|
...primaryTools,
|
69
74
|
keyboardPanZoomTool,
|
@@ -13,4 +13,5 @@ export { default as SelectionTool } from './SelectionTool/SelectionTool';
|
|
13
13
|
export { default as SelectAllShortcutHandler } from './SelectionTool/SelectAllShortcutHandler';
|
14
14
|
export { default as EraserTool } from './Eraser';
|
15
15
|
export { default as PasteHandler } from './PasteHandler';
|
16
|
+
export { default as SoundUITool } from './SoundUITool';
|
16
17
|
export { default as ToolbarShortcutHandler } from './ToolbarShortcutHandler';
|
@@ -6,7 +6,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
6
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
7
7
|
};
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
9
|
-
exports.ToolbarShortcutHandler = exports.PasteHandler = exports.EraserTool = exports.SelectAllShortcutHandler = exports.SelectionTool = exports.TextTool = exports.PenTool = exports.PanZoomMode = exports.PanZoomTool = exports.ToolSwitcherShortcut = exports.UndoRedoShortcut = exports.ToolEnabledGroup = exports.ToolController = exports.BaseTool = void 0;
|
9
|
+
exports.ToolbarShortcutHandler = exports.SoundUITool = exports.PasteHandler = exports.EraserTool = exports.SelectAllShortcutHandler = exports.SelectionTool = exports.TextTool = exports.PenTool = exports.PanZoomMode = exports.PanZoomTool = exports.ToolSwitcherShortcut = exports.UndoRedoShortcut = exports.ToolEnabledGroup = exports.ToolController = exports.BaseTool = void 0;
|
10
10
|
var BaseTool_1 = require("./BaseTool");
|
11
11
|
Object.defineProperty(exports, "BaseTool", { enumerable: true, get: function () { return __importDefault(BaseTool_1).default; } });
|
12
12
|
var ToolController_1 = require("./ToolController");
|
@@ -32,5 +32,7 @@ var Eraser_1 = require("./Eraser");
|
|
32
32
|
Object.defineProperty(exports, "EraserTool", { enumerable: true, get: function () { return __importDefault(Eraser_1).default; } });
|
33
33
|
var PasteHandler_1 = require("./PasteHandler");
|
34
34
|
Object.defineProperty(exports, "PasteHandler", { enumerable: true, get: function () { return __importDefault(PasteHandler_1).default; } });
|
35
|
+
var SoundUITool_1 = require("./SoundUITool");
|
36
|
+
Object.defineProperty(exports, "SoundUITool", { enumerable: true, get: function () { return __importDefault(SoundUITool_1).default; } });
|
35
37
|
var ToolbarShortcutHandler_1 = require("./ToolbarShortcutHandler");
|
36
38
|
Object.defineProperty(exports, "ToolbarShortcutHandler", { enumerable: true, get: function () { return __importDefault(ToolbarShortcutHandler_1).default; } });
|
@@ -13,6 +13,9 @@ export interface ToolLocalization {
|
|
13
13
|
enterTextToInsert: string;
|
14
14
|
changeTool: string;
|
15
15
|
pasteHandler: string;
|
16
|
+
soundExplorer: string;
|
17
|
+
disableAccessibilityExploreTool: string;
|
18
|
+
enableAccessibilityExploreTool: string;
|
16
19
|
findLabel: string;
|
17
20
|
toNextMatch: string;
|
18
21
|
closeFindDialog: string;
|
@@ -16,6 +16,9 @@ exports.defaultToolLocalization = {
|
|
16
16
|
enterTextToInsert: 'Text to insert',
|
17
17
|
changeTool: 'Change tool',
|
18
18
|
pasteHandler: 'Copy paste handler',
|
19
|
+
soundExplorer: 'Sound-based image exploration',
|
20
|
+
disableAccessibilityExploreTool: 'Disable sound-based exploration',
|
21
|
+
enableAccessibilityExploreTool: 'Enable sound-based exploration',
|
19
22
|
findLabel: 'Find',
|
20
23
|
toNextMatch: 'Next',
|
21
24
|
closeFindDialog: 'Close',
|
package/dist/mjs/src/Color4.d.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import Vec3 from './math/Vec3';
|
1
2
|
export default class Color4 {
|
2
3
|
/** Red component. Should be in the range [0, 1]. */
|
3
4
|
readonly r: number;
|
@@ -36,6 +37,13 @@ export default class Color4 {
|
|
36
37
|
* @returns the component-wise average of `colors`, or `Color4.transparent` if `colors` is empty.
|
37
38
|
*/
|
38
39
|
static average(colors: Color4[]): Color4;
|
40
|
+
/**
|
41
|
+
* Converts to (hue, saturation, value).
|
42
|
+
* See also https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
|
43
|
+
*
|
44
|
+
* The resultant hue is represented in radians and is thus in [0, 2pi].
|
45
|
+
*/
|
46
|
+
asHSV(): Vec3;
|
39
47
|
private hexString;
|
40
48
|
/**
|
41
49
|
* @returns a hexadecimal color string representation of `this`, in the form `#rrggbbaa`.
|
package/dist/mjs/src/Color4.mjs
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import Vec3 from './math/Vec3.mjs';
|
1
2
|
export default class Color4 {
|
2
3
|
constructor(
|
3
4
|
/** Red component. Should be in the range [0, 1]. */
|
@@ -147,6 +148,69 @@ export default class Color4 {
|
|
147
148
|
}
|
148
149
|
return new Color4(averageR, averageG, averageB, averageA);
|
149
150
|
}
|
151
|
+
/**
|
152
|
+
* Converts to (hue, saturation, value).
|
153
|
+
* See also https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
|
154
|
+
*
|
155
|
+
* The resultant hue is represented in radians and is thus in [0, 2pi].
|
156
|
+
*/
|
157
|
+
asHSV() {
|
158
|
+
// Ref: https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
|
159
|
+
//
|
160
|
+
// HUE:
|
161
|
+
// First, consider the unit cube. Rotate it such that one vertex is at the origin
|
162
|
+
// of a plane and its three neighboring vertices are equidistant from that plane:
|
163
|
+
//
|
164
|
+
// /\
|
165
|
+
// / | \
|
166
|
+
// 2 / 3 \ 1
|
167
|
+
// \ | /
|
168
|
+
// \ | /
|
169
|
+
// . \/ .
|
170
|
+
//
|
171
|
+
// .
|
172
|
+
//
|
173
|
+
// Let z be up and (x, y, 0) be in the plane.
|
174
|
+
//
|
175
|
+
// Label vectors 1,2,3 with R, G, and B, respectively. Let R's projection into the plane
|
176
|
+
// lie along the x axis.
|
177
|
+
//
|
178
|
+
// Because R is a unit vector and R, G, B are equidistant from the plane, they must
|
179
|
+
// form 30-60-90 triangles, which have side lengths proportional to (1, √3, 2)
|
180
|
+
//
|
181
|
+
// /|
|
182
|
+
// 1/ | (√3)/2
|
183
|
+
// / |
|
184
|
+
// 1/2
|
185
|
+
//
|
186
|
+
const minComponent = Math.min(this.r, this.g, this.b);
|
187
|
+
const maxComponent = Math.max(this.r, this.g, this.b);
|
188
|
+
const chroma = maxComponent - minComponent;
|
189
|
+
let hue;
|
190
|
+
// See https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
|
191
|
+
if (chroma === 0) {
|
192
|
+
hue = 0;
|
193
|
+
}
|
194
|
+
else if (this.r >= this.g && this.r >= this.b) {
|
195
|
+
hue = ((this.g - this.b) / chroma) % 6;
|
196
|
+
}
|
197
|
+
else if (this.g >= this.r && this.g >= this.b) {
|
198
|
+
hue = (this.b - this.r) / chroma + 2;
|
199
|
+
}
|
200
|
+
else {
|
201
|
+
hue = (this.r - this.g) / chroma + 4;
|
202
|
+
}
|
203
|
+
// Convert to degree representation, then to radians.
|
204
|
+
hue *= 60;
|
205
|
+
hue *= Math.PI / 180;
|
206
|
+
// Ensure positivity.
|
207
|
+
if (hue < 0) {
|
208
|
+
hue += Math.PI * 2;
|
209
|
+
}
|
210
|
+
const value = maxComponent;
|
211
|
+
const saturation = value > 0 ? chroma / value : 0;
|
212
|
+
return Vec3.of(hue, saturation, value);
|
213
|
+
}
|
150
214
|
/**
|
151
215
|
* @returns a hexadecimal color string representation of `this`, in the form `#rrggbbaa`.
|
152
216
|
*
|
package/dist/mjs/src/Editor.d.ts
CHANGED
@@ -53,7 +53,7 @@ export interface EditorSettings {
|
|
53
53
|
export declare class Editor {
|
54
54
|
private container;
|
55
55
|
private renderingRegion;
|
56
|
-
/** Manages drawing surfaces/{@link
|
56
|
+
/** Manages drawing surfaces/{@link AbstractRenderer}s. */
|
57
57
|
display: Display;
|
58
58
|
/**
|
59
59
|
* Handles undo/redo.
|
@@ -95,7 +95,7 @@ export declare class Editor {
|
|
95
95
|
readonly viewport: Viewport;
|
96
96
|
/** @internal */
|
97
97
|
readonly localization: EditorLocalization;
|
98
|
-
/** {@link
|
98
|
+
/** {@link EditorSettings.iconProvider} */
|
99
99
|
readonly icons: IconProvider;
|
100
100
|
/**
|
101
101
|
* Controls the list of tools. See
|
package/dist/mjs/src/Editor.mjs
CHANGED
@@ -31,7 +31,7 @@ import fileToBase64 from './util/fileToBase64.mjs';
|
|
31
31
|
import uniteCommands from './commands/uniteCommands.mjs';
|
32
32
|
import SelectionTool from './tools/SelectionTool/SelectionTool.mjs';
|
33
33
|
import Erase from './commands/Erase.mjs';
|
34
|
-
import
|
34
|
+
import BackgroundComponent, { BackgroundType } from './components/BackgroundComponent.mjs';
|
35
35
|
import sendPenEvent from './testing/sendPenEvent.mjs';
|
36
36
|
/**
|
37
37
|
* The main entrypoint for the full editor.
|
@@ -229,8 +229,8 @@ export class Editor {
|
|
229
229
|
if (evt.ctrlKey || evt.metaKey) {
|
230
230
|
delta = Vec3.of(0, 0, evt.deltaY);
|
231
231
|
}
|
232
|
-
// Ensure that `pos` is relative to `this.
|
233
|
-
const bbox = this.
|
232
|
+
// Ensure that `pos` is relative to `this.renderingRegion`
|
233
|
+
const bbox = this.renderingRegion.getBoundingClientRect();
|
234
234
|
const pos = Vec2.of(evt.clientX, evt.clientY).minus(Vec2.of(bbox.left, bbox.top));
|
235
235
|
if (this.toolController.dispatchInputEvent({
|
236
236
|
kind: InputEvtType.WheelEvt,
|
@@ -816,7 +816,7 @@ export class Editor {
|
|
816
816
|
// Find a background component, if one exists.
|
817
817
|
// Use the last (topmost) background component if there are multiple.
|
818
818
|
for (const component of this.image.getBackgroundComponents()) {
|
819
|
-
if (component instanceof
|
819
|
+
if (component instanceof BackgroundComponent) {
|
820
820
|
background = component;
|
821
821
|
}
|
822
822
|
}
|
@@ -829,7 +829,7 @@ export class Editor {
|
|
829
829
|
let background = this.getTopmostBackgroundComponent();
|
830
830
|
if (!background) {
|
831
831
|
const backgroundType = color.eq(Color4.transparent) ? BackgroundType.None : BackgroundType.SolidColor;
|
832
|
-
background = new
|
832
|
+
background = new BackgroundComponent(backgroundType, color);
|
833
833
|
return this.image.addElement(background);
|
834
834
|
}
|
835
835
|
else {
|
@@ -844,7 +844,7 @@ export class Editor {
|
|
844
844
|
var _a;
|
845
845
|
const backgroundColors = [];
|
846
846
|
for (const component of this.image.getBackgroundComponents()) {
|
847
|
-
if (component instanceof
|
847
|
+
if (component instanceof BackgroundComponent) {
|
848
848
|
backgroundColors.push((_a = component.getStyle().color) !== null && _a !== void 0 ? _a : Color4.transparent);
|
849
849
|
}
|
850
850
|
}
|