@lvl99dotcom/paintcanvas 0.5.0 → 0.7.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 +2 -2
- package/dist/lib/brushes/configRanges/index.d.ts +17 -0
- package/dist/lib/brushes/configRanges/index.js +31 -1
- package/dist/lib/brushes/params/index.d.ts +2 -1
- package/dist/lib/brushes/params/index.js +7 -4
- package/dist/lib/brushes/types/index.d.ts +8 -0
- package/dist/lib/classes/Layer/index.d.ts +10 -0
- package/dist/lib/classes/Layer/index.js +15 -1
- package/dist/lib/classes/LayerAutosave/index.d.ts +9 -15
- package/dist/lib/classes/LayerAutosave/index.js +30 -43
- package/dist/lib/classes/LayerStack/index.d.ts +15 -0
- package/dist/lib/classes/LayerStack/index.js +26 -2
- package/dist/lib/classes/PaintCanvas/index.d.ts +36 -5
- package/dist/lib/classes/PaintCanvas/index.js +45 -14
- package/dist/lib/classes/PngEncoder/index.d.ts +41 -0
- package/dist/lib/classes/PngEncoder/index.js +104 -0
- package/dist/lib/classes/ProfileGraphs/index.d.ts +87 -0
- package/dist/lib/classes/ProfileGraphs/index.js +148 -0
- package/dist/lib/classes/SettingsAutosave/index.d.ts +1 -1
- package/dist/lib/classes/SettingsAutosave/index.js +2 -1
- package/dist/lib/classes/UiSettings/index.d.ts +24 -2
- package/dist/lib/classes/UiSettings/index.js +32 -7
- package/dist/lib/messages/schema.d.ts +720 -0
- package/dist/lib/presets/schema.d.ts +360 -0
- package/dist/lib/presets/schema.js +8 -1
- package/dist/lib/profiles/index.d.ts +61 -0
- package/dist/lib/profiles/index.js +131 -0
- package/dist/lib/profiles/schema.d.ts +73 -0
- package/dist/lib/profiles/schema.js +53 -0
- package/dist/lib/rendering/sample/index.d.ts +11 -0
- package/dist/lib/rendering/sample/index.js +36 -5
- package/dist/lib/settings/index.d.ts +2 -1
- package/dist/lib/settings/index.js +4 -1
- package/dist/lib/settings/schema.d.ts +53 -1
- package/dist/lib/settings/schema.js +9 -2
- package/dist/lib/storage/index.d.ts +26 -0
- package/dist/lib/storage/index.js +38 -1
- package/dist/lib/validation/validators.generated.js +13061 -3675
- package/dist/lib/version/index.d.ts +25 -0
- package/dist/lib/version/index.js +35 -0
- package/dist/locales/en-GB.js +35 -0
- package/dist/locales/en-US.js +35 -0
- package/dist/locales/fr.js +35 -0
- package/dist/locales/ja.js +35 -0
- package/dist/locales/ko.js +35 -0
- package/dist/locales/zh-Hans.js +35 -0
- package/dist/locales/zh-Hant.js +35 -0
- package/dist/package.js +1 -1
- package/dist/ui/ask/index.d.ts +48 -0
- package/dist/ui/ask/index.js +67 -0
- package/dist/ui/base/index.d.ts +8 -1
- package/dist/ui/base/index.js +19 -4
- package/dist/ui/elements/PaintCanvas/index.d.ts +13 -3
- package/dist/ui/elements/PaintCanvas/index.js +25 -6
- package/dist/ui/elements/PaintCanvas/style.js +1 -1
- package/dist/ui/elements/PcAppSettings/index.d.ts +15 -7
- package/dist/ui/elements/PcAppSettings/index.js +53 -62
- package/dist/ui/elements/PcBrushConfig/index.d.ts +26 -14
- package/dist/ui/elements/PcBrushConfig/index.js +214 -145
- package/dist/ui/elements/PcBrushConfig/style.js +1 -1
- package/dist/ui/elements/PcBrushTest/index.d.ts +1 -0
- package/dist/ui/elements/PcBrushTest/index.js +15 -9
- package/dist/ui/elements/PcBrushTest/style.js +1 -1
- package/dist/ui/elements/PcButton/index.d.ts +12 -3
- package/dist/ui/elements/PcButton/index.js +18 -10
- package/dist/ui/elements/PcButtonMenu/index.d.ts +88 -0
- package/dist/ui/elements/PcButtonMenu/index.js +125 -0
- package/dist/ui/elements/PcCanvas/index.d.ts +15 -1
- package/dist/ui/elements/PcCanvas/index.js +42 -19
- package/dist/ui/elements/PcCanvas/style.js +1 -1
- package/dist/ui/elements/PcClipboardTools/index.d.ts +11 -7
- package/dist/ui/elements/PcClipboardTools/index.js +30 -29
- package/dist/ui/elements/PcDialog/index.d.ts +46 -10
- package/dist/ui/elements/PcDialog/index.js +102 -51
- package/dist/ui/elements/PcDialogWindow/index.d.ts +141 -0
- package/dist/ui/elements/PcDialogWindow/index.js +385 -0
- package/dist/ui/elements/PcInputSettings/index.d.ts +2 -1
- package/dist/ui/elements/PcInputSettings/index.js +9 -15
- package/dist/ui/elements/PcLayerItem/index.d.ts +21 -6
- package/dist/ui/elements/PcLayerItem/index.js +53 -26
- package/dist/ui/elements/PcLayerItem/style.js +1 -1
- package/dist/ui/elements/PcPanelBrushes/index.d.ts +3 -2
- package/dist/ui/elements/PcPanelBrushes/index.js +7 -5
- package/dist/ui/elements/PcPanelBrushes/style.js +1 -1
- package/dist/ui/elements/PcPanelColours/index.js +2 -2
- package/dist/ui/elements/PcPanelColours/style.js +1 -1
- package/dist/ui/elements/PcPanelLayers/index.js +1 -1
- package/dist/ui/elements/PcPanelLayers/style.js +1 -1
- package/dist/ui/elements/PcProfileEditor/index.d.ts +103 -0
- package/dist/ui/elements/PcProfileEditor/index.js +259 -0
- package/dist/ui/elements/PcProfileGraph/index.d.ts +84 -0
- package/dist/ui/elements/PcProfileGraph/index.js +317 -0
- package/dist/ui/elements/PcShortcutSettings/index.js +9 -13
- package/dist/ui/elements/PcSliderRange/index.d.ts +147 -0
- package/dist/ui/elements/PcSliderRange/index.js +308 -0
- package/dist/ui/elements/PcStats/index.d.ts +19 -4
- package/dist/ui/elements/PcStats/index.js +29 -13
- package/dist/ui/elements/PcToggleCheckbox/index.d.ts +13 -2
- package/dist/ui/elements/PcToggleCheckbox/index.js +27 -8
- package/dist/ui/elements/PcToolSettings/index.d.ts +1 -0
- package/dist/ui/elements/PcToolSettings/index.js +14 -14
- package/dist/ui/elements/PcVersion/index.d.ts +12 -0
- package/dist/ui/elements/PcVersion/index.js +43 -0
- package/dist/ui/icons/images/icon-profile-graph@2x.js +3 -0
- package/dist/ui/icons/index.d.ts +1 -1
- package/dist/ui/icons/index.js +2 -0
- package/dist/ui/index.d.ts +9 -2
- package/dist/ui/index.js +9 -2
- package/dist/ui/layout/index.d.ts +2 -2
- package/dist/ui/layout/index.js +2 -2
- package/dist/ui/styles/index.d.ts +21 -1
- package/dist/ui/styles/index.js +73 -14
- package/locales/en-GB.json +35 -0
- package/locales/en-US.json +35 -0
- package/locales/fr.json +35 -0
- package/locales/ja.json +35 -0
- package/locales/ko.json +35 -0
- package/locales/zh-Hans.json +35 -0
- package/locales/zh-Hant.json +35 -0
- package/package.json +25 -23
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
2
|
+
import { ICON_CONTROLS_CSS } from "../../styles/index.js";
|
|
3
|
+
import { iconLabel } from "../../icons/index.js";
|
|
4
|
+
import { Interpolation, linearPoints, profileY } from "../../../lib/profiles/index.js";
|
|
5
|
+
import { css, html, nothing, svg, unsafeCSS } from "lit";
|
|
6
|
+
// src/ui/elements/PcProfileGraph/index.ts
|
|
7
|
+
/** Space around the grid, in grid units, so points on its edges can be pressed */
|
|
8
|
+
var MARGIN = .6;
|
|
9
|
+
/** How close (in grid units) a press must be to the line to add a point there */
|
|
10
|
+
var LINE_REACH = .6;
|
|
11
|
+
/** Points are placed on multiples of this many grid units when dragged */
|
|
12
|
+
var SNAP = .1;
|
|
13
|
+
/** How many pieces the curve is drawn with */
|
|
14
|
+
var CURVE_STEPS = 100;
|
|
15
|
+
/** A value rounded to `SNAP` and kept within a range */
|
|
16
|
+
var snap = (value, min, max) => Math.min(max, Math.max(min, Math.round(value / SNAP) * SNAP));
|
|
17
|
+
/**
|
|
18
|
+
* The SVG path of a curve through points, drawn as short straight pieces (y is flipped: up is less negative).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* curvePath(linearPoints()); // "M0,10 L0.1,9.9 …"
|
|
22
|
+
*/
|
|
23
|
+
var curvePath = (points) => Array.from({ length: 101 }, (_, step) => {
|
|
24
|
+
const x = step / CURVE_STEPS * 10;
|
|
25
|
+
const y = Math.min(10, Math.max(0, -profileY(points, x)));
|
|
26
|
+
return `${step ? "L" : "M"}${+x.toFixed(3)},${+y.toFixed(3)}`;
|
|
27
|
+
}).join(" ");
|
|
28
|
+
/**
|
|
29
|
+
* Move a point within the grid, keeping it between its neighbours (and the first and last points at the edges), to
|
|
30
|
+
* multiples of 0.1. Returns new points.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* movePoint(points, 1, 4.04, -3); // points[1] at { x: 4, y: -3 }
|
|
34
|
+
*/
|
|
35
|
+
var movePoint = (points, index, x, y) => {
|
|
36
|
+
const last = points.length - 1;
|
|
37
|
+
const before = points[index - 1];
|
|
38
|
+
const after = points[index + 1];
|
|
39
|
+
const nextX = index === 0 ? 0 : index === last ? 10 : snap(x, before.x, after.x);
|
|
40
|
+
return points.map((point, i) => i === index ? {
|
|
41
|
+
...point,
|
|
42
|
+
x: nextX,
|
|
43
|
+
y: snap(y, -10, 0)
|
|
44
|
+
} : point);
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A profile graph to edit (see `@lvl99dotcom/paintcanvas/lib/profiles`): a 10 × 10 grid with the curve through its
|
|
48
|
+
* points, from the setting's min at the bottom left to its max at the top right.
|
|
49
|
+
*
|
|
50
|
+
* - Pressing the line adds a point there (smooth), selected.
|
|
51
|
+
* - Pressing a point selects it; dragging moves it (between its neighbours; the first and last stay at the edges).
|
|
52
|
+
* - With a point selected, the arrow keys move it a grid unit, and the buttons below make it a sharp corner (linear)
|
|
53
|
+
* or smooth (bezier cubic), or remove it (−; not the first or last).
|
|
54
|
+
*
|
|
55
|
+
* Points are focusable buttons (Tab moves between them; focusing one selects it). Fires `pc-change` (detail:
|
|
56
|
+
* `{ points }`) whenever the points change, after changing `points` itself.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* html`<pc-profile-graph .points=${points} @pc-change=${(e) => (points = e.detail.points)}></pc-profile-graph>`
|
|
60
|
+
*/
|
|
61
|
+
var PcProfileGraph = class extends PcElement {
|
|
62
|
+
static properties = {
|
|
63
|
+
...PcElement.properties,
|
|
64
|
+
points: { attribute: false },
|
|
65
|
+
selected: { type: Number },
|
|
66
|
+
label: { type: String }
|
|
67
|
+
};
|
|
68
|
+
static styles = [
|
|
69
|
+
PcElement.styles,
|
|
70
|
+
unsafeCSS(ICON_CONTROLS_CSS),
|
|
71
|
+
css`
|
|
72
|
+
:host {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
align-items: center;
|
|
76
|
+
gap: var(--pc-space-2);
|
|
77
|
+
color: var(--pc-text);
|
|
78
|
+
font-family: var(--pc-font);
|
|
79
|
+
}
|
|
80
|
+
svg {
|
|
81
|
+
width: 100%;
|
|
82
|
+
max-width: 300px;
|
|
83
|
+
aspect-ratio: 1;
|
|
84
|
+
touch-action: none;
|
|
85
|
+
cursor: crosshair;
|
|
86
|
+
user-select: none;
|
|
87
|
+
}
|
|
88
|
+
.grid {
|
|
89
|
+
stroke: var(--pc-border);
|
|
90
|
+
stroke-width: 0.03;
|
|
91
|
+
}
|
|
92
|
+
.frame {
|
|
93
|
+
fill: var(--pc-surface);
|
|
94
|
+
stroke: var(--pc-text);
|
|
95
|
+
stroke-width: 0.08;
|
|
96
|
+
}
|
|
97
|
+
.diagonal {
|
|
98
|
+
stroke: var(--pc-text-muted);
|
|
99
|
+
stroke-width: 0.03;
|
|
100
|
+
}
|
|
101
|
+
.area {
|
|
102
|
+
fill: var(--pc-surface-active);
|
|
103
|
+
}
|
|
104
|
+
.curve {
|
|
105
|
+
fill: none;
|
|
106
|
+
stroke: var(--pc-text);
|
|
107
|
+
stroke-width: 0.12;
|
|
108
|
+
}
|
|
109
|
+
.point {
|
|
110
|
+
fill: var(--pc-text);
|
|
111
|
+
stroke: var(--pc-surface);
|
|
112
|
+
stroke-width: 0.08;
|
|
113
|
+
cursor: grab;
|
|
114
|
+
outline: none;
|
|
115
|
+
}
|
|
116
|
+
.point.selected {
|
|
117
|
+
fill: var(--pc-accent);
|
|
118
|
+
stroke: var(--pc-text);
|
|
119
|
+
}
|
|
120
|
+
.point:focus-visible {
|
|
121
|
+
stroke: var(--pc-focus);
|
|
122
|
+
stroke-width: 0.15;
|
|
123
|
+
}
|
|
124
|
+
.buttons {
|
|
125
|
+
display: flex;
|
|
126
|
+
gap: var(--pc-space-2);
|
|
127
|
+
}
|
|
128
|
+
button.icon-button {
|
|
129
|
+
min-width: 32px;
|
|
130
|
+
min-height: 32px;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
align-items: center;
|
|
133
|
+
color: var(--pc-text);
|
|
134
|
+
font: inherit;
|
|
135
|
+
font-size: 20px;
|
|
136
|
+
line-height: 1;
|
|
137
|
+
}
|
|
138
|
+
`
|
|
139
|
+
];
|
|
140
|
+
/** The point being dragged */
|
|
141
|
+
dragging;
|
|
142
|
+
constructor() {
|
|
143
|
+
super();
|
|
144
|
+
this.points = linearPoints();
|
|
145
|
+
this.label = "";
|
|
146
|
+
}
|
|
147
|
+
/** Change the points and tell listeners */
|
|
148
|
+
setPoints(points) {
|
|
149
|
+
this.points = points;
|
|
150
|
+
emit(this, "pc-change", { points });
|
|
151
|
+
}
|
|
152
|
+
/** A pointer's position in grid units */
|
|
153
|
+
gridAt(event) {
|
|
154
|
+
const { left, top, width, height } = this.renderRoot.querySelector("svg").getBoundingClientRect();
|
|
155
|
+
const size = 10 + MARGIN * 2;
|
|
156
|
+
return {
|
|
157
|
+
x: (event.clientX - left) / (width || 1) * size - MARGIN,
|
|
158
|
+
y: -((event.clientY - top) / (height || 1) * size - MARGIN)
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Add a point (smooth) where a press on the line is, and select it. Does nothing away from the line or when full.
|
|
163
|
+
*/
|
|
164
|
+
onGraphDown(event) {
|
|
165
|
+
if (event.button > 0 || this.points.length >= 32) return;
|
|
166
|
+
const { x, y } = this.gridAt(event);
|
|
167
|
+
if (x <= 0 || x >= 10) return;
|
|
168
|
+
if (Math.abs(profileY(this.points, x) - y) > LINE_REACH) return;
|
|
169
|
+
const index = this.points.findIndex((point) => point.x > x);
|
|
170
|
+
const added = {
|
|
171
|
+
x: snap(x, 0, 10),
|
|
172
|
+
y: snap(profileY(this.points, x), -10, 0),
|
|
173
|
+
i: Interpolation.BezierCubic
|
|
174
|
+
};
|
|
175
|
+
this.setPoints([
|
|
176
|
+
...this.points.slice(0, index),
|
|
177
|
+
added,
|
|
178
|
+
...this.points.slice(index)
|
|
179
|
+
]);
|
|
180
|
+
this.startDrag(event, index);
|
|
181
|
+
}
|
|
182
|
+
/** Select a point and start dragging it */
|
|
183
|
+
startDrag(event, index) {
|
|
184
|
+
event.preventDefault();
|
|
185
|
+
event.stopPropagation();
|
|
186
|
+
this.selected = index;
|
|
187
|
+
this.dragging = index;
|
|
188
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
189
|
+
}
|
|
190
|
+
onMove(event) {
|
|
191
|
+
if (this.dragging === void 0) return;
|
|
192
|
+
const { x, y } = this.gridAt(event);
|
|
193
|
+
this.setPoints(movePoint(this.points, this.dragging, x, y));
|
|
194
|
+
}
|
|
195
|
+
onUp() {
|
|
196
|
+
this.dragging = void 0;
|
|
197
|
+
}
|
|
198
|
+
/** Move the selected point a grid unit with the arrow keys */
|
|
199
|
+
onPointKeyDown(event, index) {
|
|
200
|
+
const move = {
|
|
201
|
+
ArrowLeft: [-1, 0],
|
|
202
|
+
ArrowRight: [1, 0],
|
|
203
|
+
ArrowUp: [0, 1],
|
|
204
|
+
ArrowDown: [0, -1]
|
|
205
|
+
}[event.key];
|
|
206
|
+
if (!move) return;
|
|
207
|
+
event.preventDefault();
|
|
208
|
+
const point = this.points[index];
|
|
209
|
+
this.setPoints(movePoint(this.points, index, point.x + move[0], point.y + move[1]));
|
|
210
|
+
}
|
|
211
|
+
/** Make the selected point a sharp corner or smooth */
|
|
212
|
+
setInterpolation(i) {
|
|
213
|
+
const index = this.selected;
|
|
214
|
+
if (index === void 0) return;
|
|
215
|
+
this.setPoints(this.points.map((point, at) => at === index ? {
|
|
216
|
+
...point,
|
|
217
|
+
i
|
|
218
|
+
} : point));
|
|
219
|
+
}
|
|
220
|
+
/** Remove the selected point (not the first or last) */
|
|
221
|
+
removeSelected() {
|
|
222
|
+
const index = this.selected;
|
|
223
|
+
if (!index || index >= this.points.length - 1) return;
|
|
224
|
+
this.selected = void 0;
|
|
225
|
+
this.setPoints(this.points.filter((_, at) => at !== index));
|
|
226
|
+
}
|
|
227
|
+
render() {
|
|
228
|
+
const { points } = this;
|
|
229
|
+
const selected = this.selected === void 0 ? void 0 : points[this.selected];
|
|
230
|
+
const inner = this.selected !== void 0 && this.selected > 0 && this.selected < points.length - 1;
|
|
231
|
+
const curve = curvePath(points);
|
|
232
|
+
const lines = Array.from({ length: 9 }, (_, i) => i + 1);
|
|
233
|
+
const size = 10 + MARGIN * 2;
|
|
234
|
+
return html`<svg
|
|
235
|
+
part="graph"
|
|
236
|
+
viewBox="${-.6} ${-.6} ${size} ${size}"
|
|
237
|
+
role="group"
|
|
238
|
+
aria-label=${this.label || nothing}
|
|
239
|
+
@pointerdown=${this.onGraphDown}
|
|
240
|
+
@pointermove=${this.onMove}
|
|
241
|
+
@pointerup=${this.onUp}
|
|
242
|
+
@pointercancel=${this.onUp}
|
|
243
|
+
>
|
|
244
|
+
<rect
|
|
245
|
+
class="frame"
|
|
246
|
+
x="0"
|
|
247
|
+
y="0"
|
|
248
|
+
width=${10}
|
|
249
|
+
height=${10}
|
|
250
|
+
></rect>
|
|
251
|
+
<path
|
|
252
|
+
class="area"
|
|
253
|
+
d="${curve} L${10},${10} L0,${10} Z"
|
|
254
|
+
></path>
|
|
255
|
+
${lines.map((n) => svg`<line class="grid" x1=${n} y1="0" x2=${n} y2=${10}></line><line class="grid" x1="0" y1=${n} x2=${10} y2=${n}></line>`)}
|
|
256
|
+
<line
|
|
257
|
+
class="diagonal"
|
|
258
|
+
x1="0"
|
|
259
|
+
y1=${10}
|
|
260
|
+
x2=${10}
|
|
261
|
+
y2="0"
|
|
262
|
+
></line>
|
|
263
|
+
<path class="curve" d=${curve}></path>
|
|
264
|
+
${points.map((point, index) => svg`<circle
|
|
265
|
+
class="point ${index === this.selected ? "selected" : ""}"
|
|
266
|
+
cx=${point.x}
|
|
267
|
+
cy=${-point.y}
|
|
268
|
+
r="0.35"
|
|
269
|
+
tabindex="0"
|
|
270
|
+
role="button"
|
|
271
|
+
aria-pressed=${index === this.selected ? "true" : "false"}
|
|
272
|
+
aria-label=${this.t("paintCanvas.profileGraph.point", {
|
|
273
|
+
number: index + 1,
|
|
274
|
+
x: point.x,
|
|
275
|
+
y: point.y
|
|
276
|
+
})}
|
|
277
|
+
@focus=${() => this.selected = index}
|
|
278
|
+
@pointerdown=${(event) => this.startDrag(event, index)}
|
|
279
|
+
@keydown=${(event) => this.onPointKeyDown(event, index)}
|
|
280
|
+
></circle>`)}
|
|
281
|
+
</svg>
|
|
282
|
+
<div class="buttons" part="buttons">
|
|
283
|
+
<button
|
|
284
|
+
type="button"
|
|
285
|
+
class="icon-button remove"
|
|
286
|
+
title=${this.t("paintCanvas.profileGraph.remove")}
|
|
287
|
+
aria-label=${this.t("paintCanvas.profileGraph.remove")}
|
|
288
|
+
?disabled=${!inner}
|
|
289
|
+
@click=${() => this.removeSelected()}
|
|
290
|
+
>
|
|
291
|
+
−
|
|
292
|
+
</button>
|
|
293
|
+
<button
|
|
294
|
+
type="button"
|
|
295
|
+
class="icon-button linear"
|
|
296
|
+
title=${this.t("paintCanvas.profileGraph.linear")}
|
|
297
|
+
aria-pressed=${selected?.i === Interpolation.Linear ? "true" : "false"}
|
|
298
|
+
?disabled=${!selected}
|
|
299
|
+
@click=${() => this.setInterpolation(Interpolation.Linear)}
|
|
300
|
+
>
|
|
301
|
+
${iconLabel(this.iconUrl("smoothingLinear"), this.t("paintCanvas.profileGraph.linear"))}
|
|
302
|
+
</button>
|
|
303
|
+
<button
|
|
304
|
+
type="button"
|
|
305
|
+
class="icon-button bezier"
|
|
306
|
+
title=${this.t("paintCanvas.profileGraph.bezier")}
|
|
307
|
+
aria-pressed=${selected?.i === Interpolation.BezierCubic ? "true" : "false"}
|
|
308
|
+
?disabled=${!selected}
|
|
309
|
+
@click=${() => this.setInterpolation(Interpolation.BezierCubic)}
|
|
310
|
+
>
|
|
311
|
+
${iconLabel(this.iconUrl("smoothingBezierCubic"), this.t("paintCanvas.profileGraph.bezier"))}
|
|
312
|
+
</button>
|
|
313
|
+
</div>`;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
defineElement("pc-profile-graph", PcProfileGraph);
|
|
317
|
+
export { PcProfileGraph, curvePath, movePoint };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { PILLS_CSS } from "../../styles/index.js";
|
|
1
2
|
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
2
3
|
import ChangeController from "../../ChangeController/index.js";
|
|
3
4
|
import { SHORTCUT_DEFINITIONS, comboFromEvent, comboText, heldModifiers } from "../../../lib/utils/shortcuts/index.js";
|
|
4
|
-
import { css, html, nothing } from "lit";
|
|
5
|
+
import { css, html, nothing, unsafeCSS } from "lit";
|
|
5
6
|
// src/ui/elements/PcShortcutSettings/index.ts
|
|
6
7
|
/** Keys used to move through and leave the settings, which are never recorded */
|
|
7
8
|
var PASSED_KEYS = /* @__PURE__ */ new Set(["Tab", "Escape"]);
|
|
@@ -38,7 +39,10 @@ var PcShortcutSettings = class extends PcElement {
|
|
|
38
39
|
recording: { state: true },
|
|
39
40
|
status: { state: true }
|
|
40
41
|
};
|
|
41
|
-
static styles = [
|
|
42
|
+
static styles = [
|
|
43
|
+
PcElement.styles,
|
|
44
|
+
unsafeCSS(PILLS_CSS),
|
|
45
|
+
css`
|
|
42
46
|
:host {
|
|
43
47
|
display: flex;
|
|
44
48
|
flex-direction: column;
|
|
@@ -131,17 +135,9 @@ var PcShortcutSettings = class extends PcElement {
|
|
|
131
135
|
}
|
|
132
136
|
button.reset {
|
|
133
137
|
align-self: flex-start;
|
|
134
|
-
min-height: var(--pc-control-size);
|
|
135
|
-
padding: var(--pc-space-1) var(--pc-space-3);
|
|
136
|
-
border: 0;
|
|
137
|
-
border-radius: var(--pc-radius-pill);
|
|
138
|
-
background: var(--pc-accent);
|
|
139
|
-
color: var(--pc-accent-text);
|
|
140
|
-
font: inherit;
|
|
141
|
-
font-weight: bold;
|
|
142
|
-
cursor: pointer;
|
|
143
138
|
}
|
|
144
|
-
`
|
|
139
|
+
`
|
|
140
|
+
];
|
|
145
141
|
changes = new ChangeController(this, () => [this.settings]);
|
|
146
142
|
constructor() {
|
|
147
143
|
super();
|
|
@@ -259,7 +255,7 @@ var PcShortcutSettings = class extends PcElement {
|
|
|
259
255
|
<p class="status" role="status">${this.status}</p>
|
|
260
256
|
<button
|
|
261
257
|
type="button"
|
|
262
|
-
class="reset"
|
|
258
|
+
class="pill reset"
|
|
263
259
|
@click=${() => {
|
|
264
260
|
settings.reset();
|
|
265
261
|
this.status = this.t("paintCanvas.shortcuts.wasReset");
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { PcElement } from "../../base";
|
|
2
|
+
import "../PcNumberSlider";
|
|
3
|
+
/** One of a range's two ends: its lowest or highest value */
|
|
4
|
+
export type RangeEnd = "low" | "high";
|
|
5
|
+
/** What `pc-input` and `pc-change` give: the range's lowest and highest values */
|
|
6
|
+
export interface RangeDetail {
|
|
7
|
+
/** A single slider's value (the same as `high`) */
|
|
8
|
+
value: number;
|
|
9
|
+
low: number;
|
|
10
|
+
high: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Where a value sits between `min` and `max`, from 0 to 1 (0 when they're the same).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* rangeFraction(25, 0, 100); // 0.25
|
|
17
|
+
*/
|
|
18
|
+
export declare const rangeFraction: (value: number, min: number, max: number) => number;
|
|
19
|
+
/**
|
|
20
|
+
* A slider for a range: one track with two handles, the left for the lowest value (`low`) and the right for the highest
|
|
21
|
+
* (`high`), and a `<pc-number-slider>` for each on either side (dragged, or tapped to type). The two can't cross: the
|
|
22
|
+
* lowest is never above the highest. Values are kept within `min` and `max` and rounded to `step`.
|
|
23
|
+
*
|
|
24
|
+
* Pressing the track moves the nearest handle there and drags it. With keyboard focus on a handle, the arrow keys move
|
|
25
|
+
* it by `step`, Page Up and Page Down by `pageStep`, and Home and End as far as it can go. Touch, mouse and pen all work.
|
|
26
|
+
*
|
|
27
|
+
* With `single`, it's a slider for one value (`value`, from `min`): one handle, and one number slider before the track,
|
|
28
|
+
* or after it with `number-position="end"`. Use it for single values too, so they look and work the same as ranges.
|
|
29
|
+
*
|
|
30
|
+
* Fires `pc-input` (detail: `{ low, high }`) while a handle is dragged, and `pc-change` once it's let go, or when a value
|
|
31
|
+
* is changed with the keyboard or a number slider, after changing `low` and `high` themselves (and `value`, the same as
|
|
32
|
+
* `high`).
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* html`<pc-slider-range label="Width" min="1" max="256" .low=${10} .high=${40}
|
|
36
|
+
* @pc-change=${(e) => setWidth(e.detail.low, e.detail.high)}></pc-slider-range>`
|
|
37
|
+
*/
|
|
38
|
+
export declare class PcSliderRange extends PcElement {
|
|
39
|
+
static properties: {
|
|
40
|
+
low: {
|
|
41
|
+
type: NumberConstructor;
|
|
42
|
+
};
|
|
43
|
+
high: {
|
|
44
|
+
type: NumberConstructor;
|
|
45
|
+
};
|
|
46
|
+
min: {
|
|
47
|
+
type: NumberConstructor;
|
|
48
|
+
};
|
|
49
|
+
max: {
|
|
50
|
+
type: NumberConstructor;
|
|
51
|
+
};
|
|
52
|
+
step: {
|
|
53
|
+
type: NumberConstructor;
|
|
54
|
+
};
|
|
55
|
+
pageStep: {
|
|
56
|
+
type: NumberConstructor;
|
|
57
|
+
attribute: string;
|
|
58
|
+
};
|
|
59
|
+
unit: {
|
|
60
|
+
type: StringConstructor;
|
|
61
|
+
};
|
|
62
|
+
label: {
|
|
63
|
+
type: StringConstructor;
|
|
64
|
+
};
|
|
65
|
+
single: {
|
|
66
|
+
type: BooleanConstructor;
|
|
67
|
+
reflect: boolean;
|
|
68
|
+
};
|
|
69
|
+
numberPosition: {
|
|
70
|
+
type: StringConstructor;
|
|
71
|
+
attribute: string;
|
|
72
|
+
};
|
|
73
|
+
disabled: {
|
|
74
|
+
type: BooleanConstructor;
|
|
75
|
+
reflect: boolean;
|
|
76
|
+
};
|
|
77
|
+
dragging: {
|
|
78
|
+
state: boolean;
|
|
79
|
+
};
|
|
80
|
+
translations: {
|
|
81
|
+
attribute: boolean;
|
|
82
|
+
};
|
|
83
|
+
icons: {
|
|
84
|
+
attribute: boolean;
|
|
85
|
+
};
|
|
86
|
+
theme: {
|
|
87
|
+
type: StringConstructor;
|
|
88
|
+
reflect: boolean;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
static styles: import("lit").CSSResultGroup[];
|
|
92
|
+
/** The range's lowest value */
|
|
93
|
+
low: number;
|
|
94
|
+
/** The range's highest value */
|
|
95
|
+
high: number;
|
|
96
|
+
/** Lowest value either end can have (0 by default) */
|
|
97
|
+
min: number;
|
|
98
|
+
/** Highest value either end can have (100 by default) */
|
|
99
|
+
max: number;
|
|
100
|
+
/** What values are rounded to, and how much an arrow key moves a handle (1 by default) */
|
|
101
|
+
step: number;
|
|
102
|
+
/** How much Page Up and Page Down move a handle (10 steps by default) */
|
|
103
|
+
pageStep?: number;
|
|
104
|
+
/** Shown after each value, e.g. "%" */
|
|
105
|
+
unit: string;
|
|
106
|
+
/** The range's name for screen readers, e.g. "Width" (each end is named from it) */
|
|
107
|
+
label: string;
|
|
108
|
+
disabled: boolean;
|
|
109
|
+
/** Whether it's a slider for one value (`value`), with one handle and one number slider */
|
|
110
|
+
single: boolean;
|
|
111
|
+
/** Where a single slider's number slider goes: before the track (`start`, the default) or after it (`end`) */
|
|
112
|
+
numberPosition: "start" | "end";
|
|
113
|
+
/** A single slider's value: the same as `high` */
|
|
114
|
+
get value(): number;
|
|
115
|
+
set value(value: number);
|
|
116
|
+
/** What `pc-input` and `pc-change` give */
|
|
117
|
+
private get detail();
|
|
118
|
+
/** How far an end can go: not past the other end (a single slider's value can go down to `min`) */
|
|
119
|
+
private limitsOf;
|
|
120
|
+
/** An end's name for screen readers: a single slider's is its label */
|
|
121
|
+
private endLabel;
|
|
122
|
+
/** The end being dragged, if any */
|
|
123
|
+
dragging?: RangeEnd;
|
|
124
|
+
constructor();
|
|
125
|
+
/**
|
|
126
|
+
* Set one end, kept within `min` and `max`, rounded to `step`, and not past the other end, then tell listeners (with
|
|
127
|
+
* `pc-input` while dragging, or `pc-change`) if it changed.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* range.setEnd("high", 40); // high is 40, unless low is above it (then it's low)
|
|
131
|
+
*/
|
|
132
|
+
setEnd(end: RangeEnd, value: number, type?: string): void;
|
|
133
|
+
/** The value at a pointer's position along the track */
|
|
134
|
+
private valueAt;
|
|
135
|
+
/** The end nearest a value: the high end when it's above both, or past the middle of two that meet */
|
|
136
|
+
private nearestEnd;
|
|
137
|
+
private onPointerDown;
|
|
138
|
+
private onPointerMove;
|
|
139
|
+
private onPointerUp;
|
|
140
|
+
/** Move a handle with the arrow keys, Page Up and Page Down, Home and End */
|
|
141
|
+
private onHandleKeyDown;
|
|
142
|
+
/** One end's handle */
|
|
143
|
+
private renderHandle;
|
|
144
|
+
/** One end's number slider: it can't go past the other end */
|
|
145
|
+
private renderNumber;
|
|
146
|
+
render(): import("lit").TemplateResult<1>;
|
|
147
|
+
}
|