@lvl99dotcom/paintcanvas 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -15
- package/dist/lib/brushes/StrokeEngine/index.d.ts +2 -2
- package/dist/lib/brushes/StrokeEngine/index.js +26 -28
- package/dist/lib/brushes/presets/round/index.d.ts +1 -1
- package/dist/lib/brushes/presets/round/index.js +12 -7
- package/dist/lib/brushes/presets/square/index.d.ts +1 -1
- package/dist/lib/brushes/presets/square/index.js +7 -3
- package/dist/lib/brushes/shapeImage/index.d.ts +7 -3
- package/dist/lib/brushes/shapeImage/index.js +15 -9
- package/dist/lib/brushes/shapes/index.d.ts +18 -0
- package/dist/lib/brushes/shapes/index.js +86 -0
- package/dist/lib/classes/BrushSettings/index.d.ts +53 -2
- package/dist/lib/classes/BrushSettings/index.js +85 -14
- package/dist/lib/classes/KeyboardShortcuts/index.d.ts +47 -7
- package/dist/lib/classes/KeyboardShortcuts/index.js +145 -20
- package/dist/lib/classes/PaintCanvas/index.d.ts +123 -27
- package/dist/lib/classes/PaintCanvas/index.js +208 -41
- package/dist/lib/classes/PaintCanvas/tool.d.ts +15 -0
- package/dist/lib/classes/PaintCanvas/tool.js +18 -0
- package/dist/lib/classes/Palette/index.d.ts +58 -0
- package/dist/lib/classes/Palette/index.js +92 -0
- package/dist/lib/classes/SettingsAutosave/index.d.ts +53 -0
- package/dist/lib/classes/SettingsAutosave/index.js +98 -0
- package/dist/lib/classes/ShortcutSettings/index.d.ts +63 -0
- package/dist/lib/classes/ShortcutSettings/index.js +110 -0
- package/dist/lib/classes/UiSettings/index.d.ts +68 -0
- package/dist/lib/classes/UiSettings/index.js +82 -0
- package/dist/lib/palette/index.d.ts +49 -0
- package/dist/lib/palette/index.js +82 -0
- package/dist/lib/palette/schema.d.ts +45 -0
- package/dist/lib/palette/schema.js +41 -0
- package/dist/lib/rendering/cursors/index.d.ts +2 -0
- package/dist/lib/rendering/cursors/index.js +3 -1
- package/dist/lib/rendering/sample/index.js +3 -2
- package/dist/lib/settings/index.d.ts +63 -0
- package/dist/lib/settings/index.js +93 -0
- package/dist/lib/settings/schema.d.ts +168 -0
- package/dist/lib/settings/schema.js +116 -0
- package/dist/lib/storage/index.d.ts +36 -5
- package/dist/lib/storage/index.js +87 -29
- package/dist/lib/utils/colour/index.d.ts +72 -0
- package/dist/lib/utils/colour/index.js +154 -0
- package/dist/lib/utils/shortcuts/index.d.ts +174 -11
- package/dist/lib/utils/shortcuts/index.js +391 -145
- package/dist/lib/validation/validators.generated.d.ts +5 -0
- package/dist/lib/validation/validators.generated.js +1040 -1
- package/dist/locales/en-GB.js +96 -3
- package/dist/locales/en-US.js +96 -3
- package/dist/locales/fr.js +96 -3
- package/dist/locales/ja.js +96 -3
- package/dist/locales/ko.js +96 -3
- package/dist/locales/zh-Hans.js +96 -3
- package/dist/locales/zh-Hant.js +96 -3
- package/dist/package.js +1 -1
- package/dist/testing/recordingCanvas.js +2 -1
- package/dist/ui/base/index.d.ts +2 -2
- package/dist/ui/dismiss/index.d.ts +21 -0
- package/dist/ui/dismiss/index.js +27 -0
- package/dist/ui/drag/index.d.ts +51 -0
- package/dist/ui/drag/index.js +81 -0
- package/dist/ui/elements/PaintCanvas/index.d.ts +57 -50
- package/dist/ui/elements/PaintCanvas/index.js +141 -174
- package/dist/ui/elements/PaintCanvas/style.js +1 -1
- package/dist/ui/elements/PcAppSettings/index.d.ts +59 -0
- package/dist/ui/elements/PcAppSettings/index.js +222 -0
- package/dist/ui/elements/PcBrushConfig/index.d.ts +9 -2
- package/dist/ui/elements/PcBrushConfig/index.js +47 -7
- package/dist/ui/elements/PcBrushConfig/style.js +1 -1
- package/dist/ui/elements/PcBrushSize/index.d.ts +53 -0
- package/dist/ui/elements/PcBrushSize/index.js +66 -0
- package/dist/ui/elements/PcBrushTest/index.d.ts +26 -0
- package/dist/ui/elements/PcBrushTest/index.js +73 -5
- package/dist/ui/elements/PcBrushTest/style.js +1 -1
- package/dist/ui/elements/PcCanvas/index.d.ts +22 -2
- package/dist/ui/elements/PcCanvas/index.js +60 -15
- package/dist/ui/elements/PcCanvasMap/style.js +1 -1
- package/dist/ui/elements/PcClipboardTools/index.d.ts +48 -0
- package/dist/ui/elements/PcClipboardTools/index.js +118 -0
- package/dist/ui/elements/PcColourPair/index.d.ts +43 -0
- package/dist/ui/elements/PcColourPair/index.js +125 -0
- package/dist/ui/elements/PcContextMenu/index.d.ts +71 -34
- package/dist/ui/elements/PcContextMenu/index.js +128 -97
- package/dist/ui/elements/PcInputSettings/index.d.ts +13 -0
- package/dist/ui/elements/PcInputSettings/index.js +16 -1
- package/dist/ui/elements/PcLayerItem/index.d.ts +13 -34
- package/dist/ui/elements/PcLayerItem/index.js +39 -91
- package/dist/ui/elements/PcLayerItem/style.js +1 -1
- package/dist/ui/elements/PcMenu/index.d.ts +138 -0
- package/dist/ui/elements/PcMenu/index.js +296 -0
- package/dist/ui/elements/PcNumberSlider/index.d.ts +137 -0
- package/dist/ui/elements/PcNumberSlider/index.js +247 -0
- package/dist/ui/elements/PcPane/index.d.ts +120 -0
- package/dist/ui/elements/PcPane/index.js +394 -0
- package/dist/ui/elements/PcPanel/index.d.ts +26 -8
- package/dist/ui/elements/PcPanel/index.js +76 -8
- package/dist/ui/elements/{PcBrushMenu → PcPanelBrushes}/index.d.ts +22 -21
- package/dist/ui/elements/{PcBrushMenu → PcPanelBrushes}/index.js +24 -57
- package/dist/ui/elements/PcPanelBrushes/style.js +3 -0
- package/dist/ui/elements/PcPanelColours/index.d.ts +171 -0
- package/dist/ui/elements/PcPanelColours/index.js +650 -0
- package/dist/ui/elements/PcPanelColours/style.js +3 -0
- package/dist/ui/elements/{PcLayersMenu → PcPanelLayers}/index.d.ts +17 -4
- package/dist/ui/elements/{PcLayersMenu → PcPanelLayers}/index.js +17 -10
- package/dist/ui/elements/PcPanelLayers/style.js +3 -0
- package/dist/ui/elements/PcPopover/index.d.ts +39 -1
- package/dist/ui/elements/PcPopover/index.js +72 -4
- package/dist/ui/elements/PcShortcutSettings/index.d.ts +69 -0
- package/dist/ui/elements/PcShortcutSettings/index.js +273 -0
- package/dist/ui/elements/PcThemePicker/index.d.ts +17 -15
- package/dist/ui/elements/PcThemePicker/index.js +22 -21
- package/dist/ui/elements/PcToolSettings/index.d.ts +48 -9
- package/dist/ui/elements/PcToolSettings/index.js +384 -319
- package/dist/ui/elements/PcToolSettings/style.js +1 -1
- package/dist/ui/elements/PcToolbar/index.d.ts +62 -12
- package/dist/ui/elements/PcToolbar/index.js +119 -57
- package/dist/ui/elements/PcToolbar/style.js +1 -1
- package/dist/ui/icons/images/icon-brush@2x.js +3 -0
- package/dist/ui/icons/images/icon-circle-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-clipboard@2x.js +3 -0
- package/dist/ui/icons/images/icon-cog@2x.js +3 -0
- package/dist/ui/icons/images/icon-cursor@2x.js +3 -0
- package/dist/ui/icons/images/icon-diagonal-tlbr-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-diagonal-trbl-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-eraser@2x.js +3 -0
- package/dist/ui/icons/images/icon-eyedropper@2x.js +3 -0
- package/dist/ui/icons/images/icon-flip-horizontal@2x.js +3 -0
- package/dist/ui/icons/images/icon-flip-vertical@2x.js +3 -0
- package/dist/ui/icons/images/icon-focus-pen@2x.js +3 -0
- package/dist/ui/icons/images/icon-freehand-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-hidden@2x.js +3 -0
- package/dist/ui/icons/images/icon-horizontal-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-layers@2x.js +3 -0
- package/dist/ui/icons/images/icon-linked@2x.js +3 -0
- package/dist/ui/icons/images/icon-locked@2x.js +3 -0
- package/dist/ui/icons/images/icon-moon@2x.js +3 -0
- package/dist/ui/icons/images/icon-pan@2x.js +3 -0
- package/dist/ui/icons/images/icon-polygon-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-pressure@2x.js +3 -0
- package/dist/ui/icons/images/icon-randomise@2x.js +3 -0
- package/dist/ui/icons/images/icon-rectangle-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-redo@2x.js +3 -0
- package/dist/ui/icons/images/icon-rotate-90-left@2x.js +3 -0
- package/dist/ui/icons/images/icon-rotate-90-right@2x.js +3 -0
- package/dist/ui/icons/images/icon-rotate@2x.js +3 -0
- package/dist/ui/icons/images/icon-smoothing-bezier-cubic@2x.js +3 -0
- package/dist/ui/icons/images/icon-smoothing-bezier-quad@2x.js +3 -0
- package/dist/ui/icons/images/icon-smoothing-linear@2x.js +3 -0
- package/dist/ui/icons/images/icon-star@2x.js +3 -0
- package/dist/ui/icons/images/icon-sun@2x.js +3 -0
- package/dist/ui/icons/images/icon-tilt@2x.js +3 -0
- package/dist/ui/icons/images/icon-undo@2x.js +3 -0
- package/dist/ui/icons/images/icon-unlinked@2x.js +3 -0
- package/dist/ui/icons/images/icon-unlocked@2x.js +3 -0
- package/dist/ui/icons/images/icon-vertical-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-visible@2x.js +3 -0
- package/dist/ui/icons/images/icon-zoom-in@2x.js +3 -0
- package/dist/ui/icons/images/icon-zoom-out@2x.js +3 -0
- package/dist/ui/icons/images/icon-zoom@2x.js +3 -0
- package/dist/ui/icons/index.d.ts +1 -1
- package/dist/ui/icons/index.js +84 -72
- package/dist/ui/index.d.ts +13 -2
- package/dist/ui/index.js +16 -4
- package/dist/ui/layout/index.d.ts +9 -1
- package/dist/ui/layout/index.js +11 -2
- package/dist/ui/tokens/index.d.ts +5 -4
- package/dist/ui/tokens/index.js +15 -8
- package/locales/en-GB.json +96 -3
- package/locales/en-US.json +96 -3
- package/locales/fr.json +96 -3
- package/locales/ja.json +96 -3
- package/locales/ko.json +96 -3
- package/locales/zh-Hans.json +96 -3
- package/locales/zh-Hant.json +96 -3
- package/package.json +11 -4
- package/dist/ui/elements/PcBrushMenu/style.js +0 -3
- package/dist/ui/elements/PcLayersMenu/style.js +0 -3
- package/dist/ui/icons/images/brush.js +0 -3
- package/dist/ui/icons/images/circle-mask.js +0 -3
- package/dist/ui/icons/images/clipboard.js +0 -3
- package/dist/ui/icons/images/cursor.js +0 -3
- package/dist/ui/icons/images/eraser.js +0 -3
- package/dist/ui/icons/images/eyedropper.js +0 -3
- package/dist/ui/icons/images/flip-horizontal.js +0 -3
- package/dist/ui/icons/images/flip-vertical.js +0 -3
- package/dist/ui/icons/images/focus-pen.js +0 -3
- package/dist/ui/icons/images/freehand-mask.js +0 -3
- package/dist/ui/icons/images/hidden.js +0 -3
- package/dist/ui/icons/images/layers.js +0 -3
- package/dist/ui/icons/images/linked.js +0 -3
- package/dist/ui/icons/images/locked.js +0 -3
- package/dist/ui/icons/images/moon.js +0 -3
- package/dist/ui/icons/images/pan.js +0 -3
- package/dist/ui/icons/images/polygon-mask.js +0 -3
- package/dist/ui/icons/images/pressure.js +0 -3
- package/dist/ui/icons/images/randomise.js +0 -3
- package/dist/ui/icons/images/rectangle-mask.js +0 -3
- package/dist/ui/icons/images/redo.js +0 -3
- package/dist/ui/icons/images/rotate-90-left.js +0 -3
- package/dist/ui/icons/images/rotate-90-right.js +0 -3
- package/dist/ui/icons/images/smoothing-bezier-cubic.js +0 -3
- package/dist/ui/icons/images/smoothing-bezier-quad.js +0 -3
- package/dist/ui/icons/images/smoothing-linear.js +0 -3
- package/dist/ui/icons/images/star.js +0 -3
- package/dist/ui/icons/images/sun.js +0 -3
- package/dist/ui/icons/images/tilt.js +0 -3
- package/dist/ui/icons/images/undo.js +0 -3
- package/dist/ui/icons/images/unlinked.js +0 -3
- package/dist/ui/icons/images/unlocked.js +0 -3
- package/dist/ui/icons/images/visible.js +0 -3
- package/dist/ui/icons/images/zoom-in.js +0 -3
- package/dist/ui/icons/images/zoom-out.js +0 -3
- package/dist/ui/icons/images/zoom.js +0 -3
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import { Tool } from "../../../lib/classes/PaintCanvas/tool.js";
|
|
1
2
|
import style_default from "./style.js";
|
|
2
3
|
import { ICON_CONTROLS_CSS, PILLS_CSS } from "../../styles/index.js";
|
|
3
4
|
import { PcElement, defineElement } from "../../base/index.js";
|
|
4
5
|
import ChangeController from "../../ChangeController/index.js";
|
|
5
|
-
import { Panel
|
|
6
|
+
import { Panel } from "../../../lib/classes/PaintCanvas/index.js";
|
|
6
7
|
import "../../../lib/classes/BrushSettings/index.js";
|
|
7
8
|
import { MAX_ZOOM, MIN_ZOOM } from "../../../lib/classes/Viewport/index.js";
|
|
8
9
|
import { iconLabel } from "../../icons/index.js";
|
|
10
|
+
import "../PcBrushSize/index.js";
|
|
11
|
+
import "../PcNumberSlider/index.js";
|
|
12
|
+
import "../PcPopover/index.js";
|
|
9
13
|
import { html, nothing, svg, unsafeCSS } from "lit";
|
|
10
14
|
import { live } from "lit/directives/live.js";
|
|
11
15
|
import { styleMap } from "lit/directives/style-map.js";
|
|
@@ -50,6 +54,10 @@ var withSource = (preset, params, source, on) => Object.fromEntries(params.map((
|
|
|
50
54
|
* roundAngle(12.3456); // 12.35
|
|
51
55
|
*/
|
|
52
56
|
var roundAngle = (degrees) => Math.round(degrees * 100) / 100;
|
|
57
|
+
/** Largest width or height the move tool's fields go to (pixels or percent) */
|
|
58
|
+
var MAX_MOVE_SIZE = 1e4;
|
|
59
|
+
/** Shown in a move tool field while there's nothing to move */
|
|
60
|
+
var NO_VALUE = "–";
|
|
53
61
|
/** Steps of the zoom slider, across the whole zoom range */
|
|
54
62
|
var ZOOM_SLIDER_STEPS = 1e3;
|
|
55
63
|
/** How many times bigger the largest zoom is than the smallest */
|
|
@@ -80,19 +88,21 @@ var zoomPercent = (zoom) => {
|
|
|
80
88
|
const percent = zoom * 100;
|
|
81
89
|
return `${percent < 10 ? Math.round(percent * 10) / 10 : Math.round(percent)}%`;
|
|
82
90
|
};
|
|
83
|
-
/** Read a number input, or undefined if it isn't a number */
|
|
84
|
-
var numberValue = (event) => {
|
|
85
|
-
const value = event.target.valueAsNumber;
|
|
86
|
-
return Number.isFinite(value) ? value : void 0;
|
|
87
|
-
};
|
|
88
91
|
/**
|
|
89
|
-
* The bar of settings for the current tool, shown at the top of the canvas when the tool has any
|
|
92
|
+
* The bar of settings for the current tool, shown at the top of the canvas when the tool has any. The tool's settings
|
|
93
|
+
* are at the start (part `start`); the end, on the right (part `end`), is for your own items. The `start` and `end`
|
|
94
|
+
* slots add your own items to each. (Cut, copy and paste are `<pc-clipboard-tools>`.)
|
|
90
95
|
*
|
|
91
|
-
* - Brush and eraser: the preset (its name and shape; shows or hides the preset menu),
|
|
92
|
-
*
|
|
96
|
+
* - Brush and eraser: the preset (its name and shape; shows or hides the preset menu), the size (`pc-brush-size`), the
|
|
97
|
+
* size settings (a cog button that shows or hides a popover under it with pressure, tilt and focus pen mode above the
|
|
98
|
+
* width, constrain proportions and height), opacity and "Configure" (fires `pc-configure-brush` with the tool,
|
|
99
|
+
* "brush" or "eraser"). The size, width, height and opacity are `pc-number-slider`s: pressed and dragged right or up
|
|
100
|
+
* to raise them, left or down to lower them, or tapped to type a value. Focus pen mode: only pens draw, and touches
|
|
101
|
+
* are ignored while a pen is down or just lifted.
|
|
93
102
|
* - Lassos: select all, and invert selection and deselect (only while there is a mask).
|
|
94
103
|
* - Move, scale and rotate: width and height (in pixels or percent), constrain proportions, flip horizontal and vertical,
|
|
95
|
-
* angle (to 2 decimal places), rotate 90° left and right, and reset (undoes the whole transform).
|
|
104
|
+
* angle (to 2 decimal places), rotate 90° left and right, and reset (undoes the whole transform). The width, height
|
|
105
|
+
* and angle are `pc-number-slider`s.
|
|
96
106
|
* - Colour sample: point sample (the pixel under the pointer) or area sample (the average of a dragged rectangle).
|
|
97
107
|
* - Zoom: zoom in and out, a slider across the zoom range (logarithmic) with the zoom as a percentage, and reset (100%),
|
|
98
108
|
* all around the centre of the view.
|
|
@@ -100,13 +110,16 @@ var numberValue = (event) => {
|
|
|
100
110
|
* Changes to the brush or eraser apply to the current settings only, not the preset. Styling is structural only.
|
|
101
111
|
*
|
|
102
112
|
* @example
|
|
103
|
-
* html`<pc-tool-settings .app=${app}
|
|
113
|
+
* html`<pc-tool-settings .app=${app}>
|
|
114
|
+
* <button slot="end" @click=${share}>Share</button>
|
|
115
|
+
* </pc-tool-settings>`
|
|
104
116
|
*/
|
|
105
117
|
var PcToolSettings = class extends PcElement {
|
|
106
118
|
static properties = {
|
|
107
119
|
...PcElement.properties,
|
|
108
120
|
app: { attribute: false },
|
|
109
|
-
percent: { state: true }
|
|
121
|
+
percent: { state: true },
|
|
122
|
+
sizeOpen: { state: true }
|
|
110
123
|
};
|
|
111
124
|
static styles = [
|
|
112
125
|
PcElement.styles,
|
|
@@ -114,6 +127,7 @@ var PcToolSettings = class extends PcElement {
|
|
|
114
127
|
unsafeCSS(PILLS_CSS),
|
|
115
128
|
unsafeCSS(style_default)
|
|
116
129
|
];
|
|
130
|
+
placeSizeSettings = () => this.sizePopover?.placeBelow();
|
|
117
131
|
changes = new ChangeController(this, () => {
|
|
118
132
|
const app = this.app;
|
|
119
133
|
return app ? [
|
|
@@ -129,6 +143,47 @@ var PcToolSettings = class extends PcElement {
|
|
|
129
143
|
constructor() {
|
|
130
144
|
super();
|
|
131
145
|
this.percent = false;
|
|
146
|
+
this.sizeOpen = false;
|
|
147
|
+
}
|
|
148
|
+
disconnectedCallback() {
|
|
149
|
+
super.disconnectedCallback();
|
|
150
|
+
this.listenWhileSizeOpen(false);
|
|
151
|
+
}
|
|
152
|
+
/** The size settings' popover, while a brush or eraser's settings are shown */
|
|
153
|
+
get sizePopover() {
|
|
154
|
+
return this.renderRoot.querySelector("pc-popover.size-popover");
|
|
155
|
+
}
|
|
156
|
+
/** Follow the window's scrolling and resizing (or stop) */
|
|
157
|
+
listenWhileSizeOpen(open) {
|
|
158
|
+
const method = open ? "addEventListener" : "removeEventListener";
|
|
159
|
+
window[method]("scroll", this.placeSizeSettings, true);
|
|
160
|
+
window[method]("resize", this.placeSizeSettings);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Hide the size settings (e.g. on Escape or a press outside them), returning focus to their button if it was in them.
|
|
164
|
+
*/
|
|
165
|
+
closeSizeSettings() {
|
|
166
|
+
const focusWasInside = this.sizePopover.matches(":focus-within");
|
|
167
|
+
this.sizeOpen = false;
|
|
168
|
+
if (focusWasInside) this.renderRoot.querySelector(".size-settings")?.focus();
|
|
169
|
+
}
|
|
170
|
+
willUpdate(changed) {
|
|
171
|
+
super.willUpdate(changed);
|
|
172
|
+
const tool = this.app?.tool;
|
|
173
|
+
if (tool !== Tool.Brush && tool !== Tool.Eraser) this.sizeOpen = false;
|
|
174
|
+
}
|
|
175
|
+
updated(changed) {
|
|
176
|
+
super.updated(changed);
|
|
177
|
+
if (!changed.has("sizeOpen")) return;
|
|
178
|
+
this.listenWhileSizeOpen(this.sizeOpen);
|
|
179
|
+
if (this.sizeOpen) this.showSizeSettings();
|
|
180
|
+
}
|
|
181
|
+
/** Put the opened size settings under their button, once they can be measured */
|
|
182
|
+
async showSizeSettings() {
|
|
183
|
+
const popover = this.sizePopover;
|
|
184
|
+
popover.anchor = this.renderRoot.querySelector(".size-settings");
|
|
185
|
+
await popover.updateComplete;
|
|
186
|
+
popover.placeBelow();
|
|
132
187
|
}
|
|
133
188
|
/** Fire an event that crosses shadow DOM boundaries */
|
|
134
189
|
emit(type, detail) {
|
|
@@ -149,21 +204,45 @@ var PcToolSettings = class extends PcElement {
|
|
|
149
204
|
});
|
|
150
205
|
}
|
|
151
206
|
/**
|
|
152
|
-
* Render the focus pen mode toggle,
|
|
153
|
-
*
|
|
207
|
+
* Render the focus pen mode toggle, for the brush and eraser: while on, only pens draw, and touches are ignored while a
|
|
208
|
+
* pen is down or just lifted.
|
|
154
209
|
*/
|
|
155
210
|
renderFocusPen(app) {
|
|
156
|
-
|
|
157
|
-
|
|
211
|
+
const on = app.input.data.focusPen;
|
|
212
|
+
return html`<button
|
|
213
|
+
type="button"
|
|
214
|
+
class="focus-pen icon-button"
|
|
158
215
|
title=${this.t("paintCanvas.toolSettings.focusPenHint")}
|
|
216
|
+
aria-label=${this.t("paintCanvas.toolSettings.focusPen")}
|
|
217
|
+
aria-pressed=${String(on)}
|
|
218
|
+
@click=${() => app.input.update({ focusPen: !on })}
|
|
159
219
|
>
|
|
160
|
-
<
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
220
|
+
<img src=${this.iconUrl("focusPen")} alt="" />
|
|
221
|
+
</button>`;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Render a setting as a named `pc-number-slider` (dragged or typed), from 1 to 256 pixels unless given another range.
|
|
225
|
+
*/
|
|
226
|
+
renderNumberField(name, label, value, change, { min = 1, max = 256, unit = "", step = 1, dragStep = step, text = "", disabled = false } = {}) {
|
|
227
|
+
return html`<div class="field">
|
|
228
|
+
<span aria-hidden="true">${label}</span>
|
|
229
|
+
<pc-number-slider
|
|
230
|
+
class=${name}
|
|
231
|
+
min=${min}
|
|
232
|
+
max=${max}
|
|
233
|
+
step=${step}
|
|
234
|
+
drag-step=${dragStep}
|
|
235
|
+
unit=${unit}
|
|
236
|
+
label=${label}
|
|
237
|
+
.text=${text}
|
|
238
|
+
?disabled=${disabled}
|
|
239
|
+
.value=${live(value)}
|
|
240
|
+
@pc-change=${(e) => {
|
|
241
|
+
change(e.detail.value);
|
|
242
|
+
this.requestUpdate();
|
|
243
|
+
}}
|
|
244
|
+
></pc-number-slider>
|
|
245
|
+
</div>`;
|
|
167
246
|
}
|
|
168
247
|
/** Render the brush or eraser settings */
|
|
169
248
|
renderBrush(app, settings, kind) {
|
|
@@ -172,143 +251,136 @@ var PcToolSettings = class extends PcElement {
|
|
|
172
251
|
const tilt = TILT_PARAMS.some((param) => preset[param]?.useTilt);
|
|
173
252
|
const label = this.t(kind === "eraser" ? "paintCanvas.tool.eraser" : "paintCanvas.tool.brush");
|
|
174
253
|
const panel = kind === "eraser" ? Panel.Eraser : Panel.Brush;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
254
|
+
const sizeSettings = this.t("paintCanvas.toolSettings.sizeSettings");
|
|
255
|
+
return {
|
|
256
|
+
label: this.t("paintCanvas.toolSettings.settings", { tool: label }),
|
|
257
|
+
start: html`<button
|
|
258
|
+
type="button"
|
|
259
|
+
class="preset"
|
|
260
|
+
data-panel=${panel}
|
|
261
|
+
title=${this.t("paintCanvas.toolSettings.presets", { tool: label })}
|
|
262
|
+
aria-expanded=${app.panel === panel ? "true" : "false"}
|
|
263
|
+
@click=${() => app.togglePanel(panel)}
|
|
264
|
+
>
|
|
265
|
+
<span
|
|
266
|
+
class=${preset.image ? "shape-preview image" : "shape-preview"}
|
|
267
|
+
style=${styleMap({ maskImage: typeof preset.image === "string" ? `url("${preset.image}")` : void 0 })}
|
|
268
|
+
></span>
|
|
269
|
+
${preset.name ?? preset.id}
|
|
270
|
+
</button>
|
|
271
|
+
<div class="field">
|
|
272
|
+
<span aria-hidden="true">${this.t("paintCanvas.common.size")}</span>
|
|
273
|
+
<pc-brush-size
|
|
274
|
+
class="size"
|
|
275
|
+
.settings=${settings}
|
|
276
|
+
label=${this.t("paintCanvas.brushMenu.size", { tool: label })}
|
|
277
|
+
></pc-brush-size>
|
|
278
|
+
</div>
|
|
279
|
+
<button
|
|
280
|
+
type="button"
|
|
281
|
+
class="size-settings"
|
|
282
|
+
title=${sizeSettings}
|
|
283
|
+
aria-label=${sizeSettings}
|
|
284
|
+
aria-haspopup="dialog"
|
|
285
|
+
aria-expanded=${this.sizeOpen ? "true" : "false"}
|
|
286
|
+
@click=${() => this.sizeOpen = !this.sizeOpen}
|
|
287
|
+
>
|
|
288
|
+
<img src=${this.iconUrl("cog")} alt="" />
|
|
289
|
+
</button>
|
|
290
|
+
|
|
291
|
+
${this.renderNumberField("opacity", this.t("paintCanvas.common.opacity"), Math.round((preset.alpha ?? 1) * 100), (value) => settings.update({ alpha: value / 100 }), {
|
|
292
|
+
min: 0,
|
|
293
|
+
max: 100,
|
|
294
|
+
unit: "%"
|
|
295
|
+
})}
|
|
296
|
+
<button
|
|
297
|
+
type="button"
|
|
298
|
+
class="configure"
|
|
299
|
+
@click=${() => this.emit("pc-configure-brush", kind)}
|
|
300
|
+
>
|
|
301
|
+
${this.t("paintCanvas.toolSettings.configure")}
|
|
302
|
+
</button>`,
|
|
303
|
+
after: html`<pc-popover
|
|
304
|
+
class="size-popover"
|
|
305
|
+
arrow
|
|
306
|
+
label=${sizeSettings}
|
|
307
|
+
?open=${this.sizeOpen}
|
|
308
|
+
@pc-close=${this.closeSizeSettings}
|
|
209
309
|
>
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
</label>
|
|
256
|
-
<label>
|
|
257
|
-
${this.t("paintCanvas.common.opacity")}
|
|
258
|
-
<input
|
|
259
|
-
type="number"
|
|
260
|
-
class="opacity"
|
|
261
|
-
min="0"
|
|
262
|
-
max="100"
|
|
263
|
-
.value=${String(Math.round((preset.alpha ?? 1) * 100))}
|
|
264
|
-
@change=${(e) => {
|
|
265
|
-
const value = numberValue(e);
|
|
266
|
-
if (value !== void 0) settings.update({ alpha: Math.max(0, Math.min(100, value)) / 100 });
|
|
267
|
-
}}
|
|
268
|
-
/>
|
|
269
|
-
<span class="unit">%</span>
|
|
270
|
-
</label>
|
|
271
|
-
<button
|
|
272
|
-
type="button"
|
|
273
|
-
class="configure"
|
|
274
|
-
@click=${() => this.emit("pc-configure-brush", kind)}
|
|
275
|
-
>
|
|
276
|
-
${this.t("paintCanvas.toolSettings.configure")}
|
|
277
|
-
</button>
|
|
278
|
-
${this.renderFocusPen(app)}
|
|
279
|
-
</div>`;
|
|
310
|
+
<div class="size-toggles">
|
|
311
|
+
<label
|
|
312
|
+
class="icon-toggle"
|
|
313
|
+
title=${this.t("paintCanvas.toolSettings.pressure")}
|
|
314
|
+
>
|
|
315
|
+
<input
|
|
316
|
+
type="checkbox"
|
|
317
|
+
class="pressure"
|
|
318
|
+
.checked=${pressure}
|
|
319
|
+
@change=${(e) => settings.update(withSource(preset, PRESSURE_PARAMS, "usePressure", e.target.checked))}
|
|
320
|
+
/>
|
|
321
|
+
${iconLabel(this.iconUrl("pressure"), this.t("paintCanvas.toolSettings.pressure"))}
|
|
322
|
+
</label>
|
|
323
|
+
<label
|
|
324
|
+
class="icon-toggle"
|
|
325
|
+
title=${this.t("paintCanvas.toolSettings.tilt")}
|
|
326
|
+
>
|
|
327
|
+
<input
|
|
328
|
+
type="checkbox"
|
|
329
|
+
class="tilt"
|
|
330
|
+
.checked=${tilt}
|
|
331
|
+
@change=${(e) => settings.update(withSource(preset, TILT_PARAMS, "useTilt", e.target.checked))}
|
|
332
|
+
/>
|
|
333
|
+
${iconLabel(this.iconUrl("tilt"), this.t("paintCanvas.toolSettings.tilt"))}
|
|
334
|
+
</label>
|
|
335
|
+
${this.renderFocusPen(app)}
|
|
336
|
+
</div>
|
|
337
|
+
<div class="size-fields">
|
|
338
|
+
${this.renderNumberField("width", this.t("paintCanvas.common.width"), settings.width, (value) => settings.setSize(value, settings.height))}
|
|
339
|
+
<label
|
|
340
|
+
class="icon-toggle"
|
|
341
|
+
title=${this.t("paintCanvas.toolSettings.constrainProportions")}
|
|
342
|
+
>
|
|
343
|
+
<input
|
|
344
|
+
type="checkbox"
|
|
345
|
+
class="constrain"
|
|
346
|
+
.checked=${preset.constrainProportions ?? false}
|
|
347
|
+
@change=${(e) => settings.update({ constrainProportions: e.target.checked })}
|
|
348
|
+
/>
|
|
349
|
+
${iconLabel(this.iconUrl(preset.constrainProportions ? "linked" : "unlinked"), this.t("paintCanvas.toolSettings.constrainProportions"))}
|
|
350
|
+
</label>
|
|
351
|
+
${this.renderNumberField("height", this.t("paintCanvas.common.height"), settings.height, (value) => settings.setHeight(value))}
|
|
352
|
+
</div>
|
|
353
|
+
</pc-popover>`
|
|
354
|
+
};
|
|
280
355
|
}
|
|
281
356
|
/** Render the mask settings */
|
|
282
357
|
renderMask(app) {
|
|
283
|
-
return
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
</button>
|
|
310
|
-
${this.renderFocusPen(app)}
|
|
311
|
-
</div>`;
|
|
358
|
+
return {
|
|
359
|
+
label: this.t("paintCanvas.toolSettings.maskSettings"),
|
|
360
|
+
start: html`<button
|
|
361
|
+
type="button"
|
|
362
|
+
class="pill select-all"
|
|
363
|
+
@click=${() => app.selection.selectAll()}
|
|
364
|
+
>
|
|
365
|
+
${this.t("paintCanvas.toolSettings.selectAll")}
|
|
366
|
+
</button>
|
|
367
|
+
<button
|
|
368
|
+
type="button"
|
|
369
|
+
class="pill invert"
|
|
370
|
+
?disabled=${!app.selection.active}
|
|
371
|
+
@click=${() => app.selection.invert()}
|
|
372
|
+
>
|
|
373
|
+
${this.t("paintCanvas.toolSettings.invertSelection")}
|
|
374
|
+
</button>
|
|
375
|
+
<button
|
|
376
|
+
type="button"
|
|
377
|
+
class="pill deselect"
|
|
378
|
+
?disabled=${!app.selection.active}
|
|
379
|
+
@click=${() => app.selection.clear()}
|
|
380
|
+
>
|
|
381
|
+
${this.t("paintCanvas.toolSettings.deselect")}
|
|
382
|
+
</button>`
|
|
383
|
+
};
|
|
312
384
|
}
|
|
313
385
|
/**
|
|
314
386
|
* Resize the move tool's box to a width or height (in the current unit), keeping flips, and the other side in
|
|
@@ -318,7 +390,6 @@ var PcToolSettings = class extends PcElement {
|
|
|
318
390
|
const { box, source } = app.transform;
|
|
319
391
|
if (!box || !source) return;
|
|
320
392
|
const pixels = this.percent ? source[side] * value / 100 : value;
|
|
321
|
-
if (pixels <= 0) return;
|
|
322
393
|
const other = side === "width" ? "height" : "width";
|
|
323
394
|
const ratio = Math.abs(box[other] / box[side]);
|
|
324
395
|
app.transform.setBox({
|
|
@@ -327,118 +398,101 @@ var PcToolSettings = class extends PcElement {
|
|
|
327
398
|
...app.constrainProportions ? { [other]: Math.sign(box[other]) * pixels * ratio } : {}
|
|
328
399
|
});
|
|
329
400
|
}
|
|
330
|
-
/** A box side in the current unit
|
|
401
|
+
/** A box side in the current unit (pixels or percent) */
|
|
331
402
|
sideValue(box, source, side) {
|
|
332
403
|
const pixels = Math.abs(box[side]);
|
|
333
|
-
return
|
|
404
|
+
return Math.round(this.percent ? pixels / source[side] * 100 : pixels);
|
|
334
405
|
}
|
|
335
406
|
/** Render the move, scale and rotate settings */
|
|
336
407
|
renderMove(app) {
|
|
337
408
|
const { box, source } = app.transform;
|
|
338
409
|
const disabled = !box || !source;
|
|
339
|
-
const side = (name, label) =>
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
?disabled=${disabled}
|
|
346
|
-
.value=${box && source ? this.sideValue(box, source, name) : ""}
|
|
347
|
-
@change=${(e) => {
|
|
348
|
-
const value = numberValue(e);
|
|
349
|
-
if (value !== void 0) this.resizeBox(app, name, value);
|
|
350
|
-
}}
|
|
351
|
-
/>
|
|
352
|
-
</label>`;
|
|
410
|
+
const side = (name, label) => this.renderNumberField(name, label, box && source ? this.sideValue(box, source, name) : 0, (value) => this.resizeBox(app, name, value), {
|
|
411
|
+
max: MAX_MOVE_SIZE,
|
|
412
|
+
unit: this.percent ? "%" : "",
|
|
413
|
+
text: disabled ? NO_VALUE : "",
|
|
414
|
+
disabled
|
|
415
|
+
});
|
|
353
416
|
const rotate = (by) => this.changeBox(app, (current) => ({ rotation: by(current.rotation) % 360 }));
|
|
354
|
-
return
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
${
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
class="icon-button flip-horizontal"
|
|
384
|
-
title=${this.t("paintCanvas.toolSettings.flipHorizontal")}
|
|
385
|
-
?disabled=${disabled}
|
|
386
|
-
@click=${() => this.changeBox(app, (current) => ({ width: -current.width }))}
|
|
387
|
-
>
|
|
388
|
-
${iconLabel(this.iconUrl("flipHorizontal"), this.t("paintCanvas.toolSettings.flipHorizontal"))}
|
|
389
|
-
</button>
|
|
390
|
-
<button
|
|
391
|
-
type="button"
|
|
392
|
-
class="icon-button flip-vertical"
|
|
393
|
-
title=${this.t("paintCanvas.toolSettings.flipVertical")}
|
|
394
|
-
?disabled=${disabled}
|
|
395
|
-
@click=${() => this.changeBox(app, (current) => ({ height: -current.height }))}
|
|
396
|
-
>
|
|
397
|
-
${iconLabel(this.iconUrl("flipVertical"), this.t("paintCanvas.toolSettings.flipVertical"))}
|
|
398
|
-
</button>
|
|
399
|
-
<label>
|
|
400
|
-
${this.t("paintCanvas.toolSettings.angle")}
|
|
401
|
-
<input
|
|
402
|
-
type="number"
|
|
403
|
-
class="angle"
|
|
404
|
-
step="0.01"
|
|
417
|
+
return {
|
|
418
|
+
label: this.t("paintCanvas.toolSettings.settings", { tool: this.t("paintCanvas.tool.move") }),
|
|
419
|
+
start: html`${side("width", this.t("paintCanvas.common.width"))}
|
|
420
|
+
<label
|
|
421
|
+
class="icon-toggle"
|
|
422
|
+
title=${this.t("paintCanvas.toolSettings.constrainProportions")}
|
|
423
|
+
>
|
|
424
|
+
<input
|
|
425
|
+
type="checkbox"
|
|
426
|
+
class="constrain"
|
|
427
|
+
.checked=${live(app.constrainProportions)}
|
|
428
|
+
@change=${(e) => app.setConstrainProportions(e.target.checked)}
|
|
429
|
+
/>
|
|
430
|
+
${iconLabel(this.iconUrl(app.constrainProportions ? "linked" : "unlinked"), this.t("paintCanvas.toolSettings.constrainProportions"))}
|
|
431
|
+
</label>
|
|
432
|
+
${side("height", this.t("paintCanvas.common.height"))}
|
|
433
|
+
<label>
|
|
434
|
+
<input
|
|
435
|
+
type="checkbox"
|
|
436
|
+
class="percent"
|
|
437
|
+
.checked=${this.percent}
|
|
438
|
+
@change=${(e) => this.percent = e.target.checked}
|
|
439
|
+
/>
|
|
440
|
+
${this.t("paintCanvas.toolSettings.percent")}
|
|
441
|
+
</label>
|
|
442
|
+
<button
|
|
443
|
+
type="button"
|
|
444
|
+
class="icon-button flip-horizontal"
|
|
445
|
+
title=${this.t("paintCanvas.toolSettings.flipHorizontal")}
|
|
405
446
|
?disabled=${disabled}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
447
|
+
@click=${() => this.changeBox(app, (current) => ({ width: -current.width }))}
|
|
448
|
+
>
|
|
449
|
+
${iconLabel(this.iconUrl("flipHorizontal"), this.t("paintCanvas.toolSettings.flipHorizontal"))}
|
|
450
|
+
</button>
|
|
451
|
+
<button
|
|
452
|
+
type="button"
|
|
453
|
+
class="icon-button flip-vertical"
|
|
454
|
+
title=${this.t("paintCanvas.toolSettings.flipVertical")}
|
|
455
|
+
?disabled=${disabled}
|
|
456
|
+
@click=${() => this.changeBox(app, (current) => ({ height: -current.height }))}
|
|
457
|
+
>
|
|
458
|
+
${iconLabel(this.iconUrl("flipVertical"), this.t("paintCanvas.toolSettings.flipVertical"))}
|
|
459
|
+
</button>
|
|
460
|
+
${this.renderNumberField("angle", this.t("paintCanvas.toolSettings.angle"), box ? roundAngle(box.rotation) : 0, (value) => rotate(() => roundAngle(value)), {
|
|
461
|
+
min: -360,
|
|
462
|
+
max: 360,
|
|
463
|
+
step: .01,
|
|
464
|
+
dragStep: 1,
|
|
465
|
+
unit: "°",
|
|
466
|
+
text: disabled ? NO_VALUE : "",
|
|
467
|
+
disabled
|
|
468
|
+
})}
|
|
469
|
+
<button
|
|
470
|
+
type="button"
|
|
471
|
+
class="icon-button rotate-left"
|
|
472
|
+
title=${this.t("paintCanvas.toolSettings.rotateLeft")}
|
|
473
|
+
?disabled=${disabled}
|
|
474
|
+
@click=${() => rotate((rotation) => rotation - 90)}
|
|
475
|
+
>
|
|
476
|
+
${iconLabel(this.iconUrl("rotate90Left"), this.t("paintCanvas.toolSettings.rotateLeft"))}
|
|
477
|
+
</button>
|
|
478
|
+
<button
|
|
479
|
+
type="button"
|
|
480
|
+
class="icon-button rotate-right"
|
|
481
|
+
title=${this.t("paintCanvas.toolSettings.rotateRight")}
|
|
482
|
+
?disabled=${disabled}
|
|
483
|
+
@click=${() => rotate((rotation) => rotation + 90)}
|
|
484
|
+
>
|
|
485
|
+
${iconLabel(this.iconUrl("rotate90Right"), this.t("paintCanvas.toolSettings.rotateRight"))}
|
|
486
|
+
</button>
|
|
487
|
+
<button
|
|
488
|
+
type="button"
|
|
489
|
+
class="pill reset"
|
|
490
|
+
?disabled=${disabled}
|
|
491
|
+
@click=${() => app.cancelTransform()}
|
|
492
|
+
>
|
|
493
|
+
${this.t("paintCanvas.toolSettings.reset")}
|
|
494
|
+
</button>`
|
|
495
|
+
};
|
|
442
496
|
}
|
|
443
497
|
/** Render the zoom settings */
|
|
444
498
|
renderZoom(app) {
|
|
@@ -447,52 +501,49 @@ var PcToolSettings = class extends PcElement {
|
|
|
447
501
|
x: view.width / 2,
|
|
448
502
|
y: view.height / 2
|
|
449
503
|
};
|
|
450
|
-
return
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
<
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
<
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
<
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
</button>
|
|
494
|
-
${this.renderFocusPen(app)}
|
|
495
|
-
</div>`;
|
|
504
|
+
return {
|
|
505
|
+
label: this.t("paintCanvas.toolSettings.settings", { tool: this.t("paintCanvas.tool.zoom") }),
|
|
506
|
+
start: html`<button
|
|
507
|
+
type="button"
|
|
508
|
+
class="zoom-in"
|
|
509
|
+
title=${this.t("paintCanvas.toolSettings.zoomIn")}
|
|
510
|
+
aria-label=${this.t("paintCanvas.toolSettings.zoomIn")}
|
|
511
|
+
?disabled=${view.zoom >= MAX_ZOOM}
|
|
512
|
+
@click=${() => view.zoomIn(centre)}
|
|
513
|
+
>
|
|
514
|
+
<img src=${this.iconUrl("zoomIn")} alt="" />
|
|
515
|
+
</button>
|
|
516
|
+
<button
|
|
517
|
+
type="button"
|
|
518
|
+
class="zoom-out"
|
|
519
|
+
title=${this.t("paintCanvas.toolSettings.zoomOut")}
|
|
520
|
+
aria-label=${this.t("paintCanvas.toolSettings.zoomOut")}
|
|
521
|
+
?disabled=${view.zoom <= MIN_ZOOM}
|
|
522
|
+
@click=${() => view.zoomOut(centre)}
|
|
523
|
+
>
|
|
524
|
+
<img src=${this.iconUrl("zoomOut")} alt="" />
|
|
525
|
+
</button>
|
|
526
|
+
<label>
|
|
527
|
+
${this.t("paintCanvas.tool.zoom")}
|
|
528
|
+
<input
|
|
529
|
+
type="range"
|
|
530
|
+
class="zoom"
|
|
531
|
+
min="0"
|
|
532
|
+
max=${ZOOM_SLIDER_STEPS}
|
|
533
|
+
step="1"
|
|
534
|
+
.value=${String(zoomToSlider(view.zoom))}
|
|
535
|
+
@input=${(e) => view.zoomAt(centre, sliderToZoom(e.target.valueAsNumber))}
|
|
536
|
+
/>
|
|
537
|
+
<output>${zoomPercent(view.zoom)}</output>
|
|
538
|
+
</label>
|
|
539
|
+
<button
|
|
540
|
+
type="button"
|
|
541
|
+
class="pill reset"
|
|
542
|
+
@click=${() => view.zoomAt(centre, 1)}
|
|
543
|
+
>
|
|
544
|
+
${this.t("paintCanvas.toolSettings.reset")}
|
|
545
|
+
</button>`
|
|
546
|
+
};
|
|
496
547
|
}
|
|
497
548
|
/** Render the colour sample tool's settings: point or area sampling */
|
|
498
549
|
renderColourSample(app) {
|
|
@@ -505,11 +556,9 @@ var PcToolSettings = class extends PcElement {
|
|
|
505
556
|
this.t("paintCanvas.toolSettings.areaSample"),
|
|
506
557
|
svg`<defs><linearGradient id="area-gradient"><stop offset="0" stop-color="currentColor" stop-opacity="0" /><stop offset="1" stop-color="currentColor" /></linearGradient></defs><rect x="2" y="4" width="16" height="12" fill="url(#area-gradient)" />`
|
|
507
558
|
]];
|
|
508
|
-
return
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
>
|
|
512
|
-
${modes.map(([mode, label, icon]) => html`<button
|
|
559
|
+
return {
|
|
560
|
+
label: this.t("paintCanvas.toolSettings.settings", { tool: this.t("paintCanvas.tool.colourSample") }),
|
|
561
|
+
start: html`${modes.map(([mode, label, icon]) => html`<button
|
|
513
562
|
type="button"
|
|
514
563
|
class="sample-${mode}"
|
|
515
564
|
title=${label}
|
|
@@ -528,22 +577,38 @@ var PcToolSettings = class extends PcElement {
|
|
|
528
577
|
>
|
|
529
578
|
${icon}
|
|
530
579
|
</svg>
|
|
531
|
-
</button>`)}
|
|
532
|
-
|
|
533
|
-
</div>`;
|
|
580
|
+
</button>`)}`
|
|
581
|
+
};
|
|
534
582
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
if (!app) return nothing;
|
|
583
|
+
/** The current tool's settings, if it has any */
|
|
584
|
+
toolView(app) {
|
|
538
585
|
switch (app.tool) {
|
|
539
586
|
case Tool.Brush: return this.renderBrush(app, app.brush, "brush");
|
|
540
587
|
case Tool.Eraser: return this.renderBrush(app, app.eraser, "eraser");
|
|
541
588
|
case Tool.Move: return this.renderMove(app);
|
|
542
589
|
case Tool.Zoom: return this.renderZoom(app);
|
|
543
590
|
case Tool.ColourSample: return this.renderColourSample(app);
|
|
544
|
-
default: return MASK_TOOLS.includes(app.tool) ? this.renderMask(app) :
|
|
591
|
+
default: return MASK_TOOLS.includes(app.tool) ? this.renderMask(app) : void 0;
|
|
545
592
|
}
|
|
546
593
|
}
|
|
594
|
+
render() {
|
|
595
|
+
const app = this.app;
|
|
596
|
+
const view = app && this.toolView(app);
|
|
597
|
+
if (!view) return nothing;
|
|
598
|
+
return html`<div
|
|
599
|
+
role="toolbar"
|
|
600
|
+
aria-label=${view.label}
|
|
601
|
+
@scroll=${this.placeSizeSettings}
|
|
602
|
+
>
|
|
603
|
+
<div class="start" part="start">
|
|
604
|
+
${view.start}<slot name="start"></slot>
|
|
605
|
+
</div>
|
|
606
|
+
<div class="end" part="end">
|
|
607
|
+
<slot name="end"></slot>
|
|
608
|
+
</div>
|
|
609
|
+
</div>
|
|
610
|
+
${view.after ?? nothing}`;
|
|
611
|
+
}
|
|
547
612
|
};
|
|
548
613
|
defineElement("pc-tool-settings", PcToolSettings);
|
|
549
|
-
export { PcToolSettings, ZOOM_SLIDER_STEPS, hasToolSettings, roundAngle, sliderToZoom, withSource, zoomPercent, zoomToSlider };
|
|
614
|
+
export { MAX_MOVE_SIZE, PcToolSettings, ZOOM_SLIDER_STEPS, hasToolSettings, roundAngle, sliderToZoom, withSource, zoomPercent, zoomToSlider };
|