@pixerate/editor-svelte 0.108.0 → 0.109.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/dist/canvas/createCanvasPlaybackSurface.svelte.d.ts +8 -2
- package/dist/canvas/createCanvasPlaybackSurface.svelte.js +13 -8
- package/dist/image-editor/AdjustmentLayersPanel.svelte +27 -26
- package/dist/image-editor/AdjustmentLayersPanel.svelte.d.ts +2 -0
- package/dist/image-editor/BrushOptionsBar.svelte +35 -34
- package/dist/image-editor/ColorProfilePanel.svelte +12 -12
- package/dist/image-editor/ControlSlider.svelte +6 -4
- package/dist/image-editor/ControlSlider.svelte.d.ts +2 -0
- package/dist/image-editor/CurvesEditor.svelte +6 -4
- package/dist/image-editor/CurvesEditor.svelte.d.ts +2 -0
- package/dist/image-editor/FreeTransformOptionsBar.svelte +22 -21
- package/dist/image-editor/Histogram.svelte +1 -1
- package/dist/image-editor/ImageEditor.svelte +127 -142
- package/dist/image-editor/ImageEffectControls.svelte +15 -11
- package/dist/image-editor/ImageEffectControls.svelte.d.ts +2 -0
- package/dist/image-editor/ImageProviderEffectsPanel.svelte +15 -15
- package/dist/image-editor/LayerEffectsPanel.svelte +22 -23
- package/dist/image-editor/LayersPanel.svelte +39 -39
- package/dist/image-editor/RefineEdgePanel.svelte +14 -13
- package/dist/image-editor/SelectionOptionsBar.svelte +12 -11
- package/dist/image-editor/ShapeOptionsBar.svelte +14 -13
- package/dist/image-editor/TypeOptionsBar.svelte +12 -11
- package/dist/image-editor/styles.d.ts +51 -0
- package/dist/image-editor/styles.js +51 -0
- package/dist/playback/playback.svelte.d.ts +7 -4
- package/dist/playback/playback.svelte.js +17 -9
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { imageChipClass, imageFieldClass } from './styles.js';
|
|
2
3
|
import type { FreeTransformField, FreeTransformTool, Interpolation, WarpBar } from '@pixerate/editor/image-editor';
|
|
3
4
|
import { FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, INTERPOLATIONS, TRANSFORM_ANCHORS, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS } from '@pixerate/editor/image-editor';
|
|
4
5
|
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
return { bar: tool.active ? tool.bar() : null, mode: tool.mode, proportional: tool.proportional, interpolation: tool.interpolation, error: tool.error, warp: tool.warpBar() };
|
|
22
23
|
});
|
|
23
24
|
const bar = $derived(view.bar);
|
|
24
|
-
|
|
25
|
+
|
|
25
26
|
const round = (v: number, unit: string) => (unit === 'px' ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100);
|
|
26
27
|
|
|
27
28
|
const WARP_NUMBERS = [
|
|
@@ -43,22 +44,22 @@
|
|
|
43
44
|
</script>
|
|
44
45
|
|
|
45
46
|
{#if bar}
|
|
46
|
-
<div class="flex flex-wrap items-center gap-2 text-xs text-
|
|
47
|
+
<div class="flex flex-wrap items-center gap-2 text-xs text-foreground {className}" data-testid="free-transform-options" role="toolbar" aria-label="Free Transform options">
|
|
47
48
|
<div class="flex gap-1" role="group" aria-label="Transform mode">
|
|
48
49
|
{#each FREE_TRANSFORM_MODE_OPTIONS as m (m.id)}
|
|
49
|
-
<button type="button" title={m.title} aria-pressed={view.mode === m.id} class={
|
|
50
|
+
<button type="button" title={m.title} aria-pressed={view.mode === m.id} class={imageChipClass(view.mode === m.id)} onclick={() => tool.setMode(m.id)}>{m.label}</button>
|
|
50
51
|
{/each}
|
|
51
52
|
</div>
|
|
52
53
|
<div class="grid grid-cols-3 gap-px" role="group" aria-label="Reference point">
|
|
53
54
|
{#each TRANSFORM_ANCHORS as a (a)}
|
|
54
|
-
<button type="button" aria-label={`Reference point ${a}`} title={`Reference point: ${a}`} class="h-2.5 w-2.5 rounded-sm bg-
|
|
55
|
+
<button type="button" aria-label={`Reference point ${a}`} title={`Reference point: ${a}`} class="h-2.5 w-2.5 rounded-sm bg-accent hover:bg-primary/90" onclick={() => tool.setReference(a)}></button>
|
|
55
56
|
{/each}
|
|
56
57
|
</div>
|
|
57
58
|
{#if view.mode === 'warp'}
|
|
58
59
|
<div class="flex flex-wrap items-center gap-2" role="group" aria-label="Warp options">
|
|
59
60
|
<label class="flex items-center gap-1">
|
|
60
|
-
<span class="text-
|
|
61
|
-
<select aria-label="Warp style" value={view.warp.style} onchange={(e) => tool.setWarp({ style: e.currentTarget.value as WarpBar['style'] })} class=
|
|
61
|
+
<span class="text-muted-foreground">Warp</span>
|
|
62
|
+
<select aria-label="Warp style" value={view.warp.style} onchange={(e) => tool.setWarp({ style: e.currentTarget.value as WarpBar['style'] })} class={imageFieldClass}>
|
|
62
63
|
{#each WARP_STYLE_OPTIONS as o (o.id)}
|
|
63
64
|
<option value={o.id}>{o.label}</option>
|
|
64
65
|
{/each}
|
|
@@ -66,7 +67,7 @@
|
|
|
66
67
|
</label>
|
|
67
68
|
{#each WARP_NUMBERS as n (n.key)}
|
|
68
69
|
<label class="flex items-center gap-1">
|
|
69
|
-
<span class="text-
|
|
70
|
+
<span class="text-muted-foreground">{n.label}</span>
|
|
70
71
|
{#key view.warp[n.key]}
|
|
71
72
|
<input
|
|
72
73
|
type="number"
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
min={-100}
|
|
76
77
|
max={100}
|
|
77
78
|
disabled={view.warp.style === 'custom'}
|
|
78
|
-
class="w-14 rounded border border-
|
|
79
|
+
class="w-14 rounded border border-border bg-background px-1 py-0.5 text-right disabled:opacity-40"
|
|
79
80
|
onblur={(e) => warpNumber(n.key, e.currentTarget.value)}
|
|
80
81
|
onkeydown={(e) => {
|
|
81
82
|
if (e.key === 'Enter') {
|
|
@@ -86,7 +87,7 @@
|
|
|
86
87
|
}}
|
|
87
88
|
/>
|
|
88
89
|
{/key}
|
|
89
|
-
<span class="text-
|
|
90
|
+
<span class="text-muted-foreground">%</span>
|
|
90
91
|
</label>
|
|
91
92
|
{/each}
|
|
92
93
|
<button
|
|
@@ -94,10 +95,10 @@
|
|
|
94
95
|
title="Bend along the vertical axis"
|
|
95
96
|
aria-pressed={view.warp.orientation === 'vertical'}
|
|
96
97
|
disabled={view.warp.style === 'custom'}
|
|
97
|
-
class={
|
|
98
|
+
class={imageChipClass(view.warp.orientation === 'vertical')}
|
|
98
99
|
onclick={() => tool.setWarp({ orientation: view.warp.orientation === 'vertical' ? 'horizontal' : 'vertical' })}>Vertical</button>
|
|
99
100
|
<label class="flex items-center gap-1">
|
|
100
|
-
<span class="text-
|
|
101
|
+
<span class="text-muted-foreground">Grid</span>
|
|
101
102
|
<select
|
|
102
103
|
aria-label="Warp grid"
|
|
103
104
|
value={gridId(view.warp)}
|
|
@@ -105,7 +106,7 @@
|
|
|
105
106
|
const g = WARP_GRID_OPTIONS.find((o) => o.id === e.currentTarget.value)!;
|
|
106
107
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
107
108
|
}}
|
|
108
|
-
class=
|
|
109
|
+
class={imageFieldClass}
|
|
109
110
|
>
|
|
110
111
|
{#each WARP_GRID_OPTIONS as g (g.id)}
|
|
111
112
|
<option value={g.id}>{g.label}</option>
|
|
@@ -116,7 +117,7 @@
|
|
|
116
117
|
{/if}
|
|
117
118
|
{#each view.mode === 'warp' ? [] : FREE_TRANSFORM_FIELDS as f (f.id)}
|
|
118
119
|
<label class="flex items-center gap-1" title={f.title}>
|
|
119
|
-
<span class="text-
|
|
120
|
+
<span class="text-muted-foreground">{f.label}</span>
|
|
120
121
|
{#key round(bar[f.id], f.unit)}
|
|
121
122
|
<input
|
|
122
123
|
type="number"
|
|
@@ -124,7 +125,7 @@
|
|
|
124
125
|
value={round(bar[f.id], f.unit)}
|
|
125
126
|
disabled={!bar.affine}
|
|
126
127
|
step={f.unit === 'px' ? 1 : 0.1}
|
|
127
|
-
class="w-16 rounded border border-
|
|
128
|
+
class="w-16 rounded border border-border bg-background px-1 py-0.5 text-right disabled:opacity-40"
|
|
128
129
|
onblur={(e) => apply(f.id, e.currentTarget.value)}
|
|
129
130
|
onkeydown={(e) => {
|
|
130
131
|
if (e.key === 'Enter') {
|
|
@@ -135,13 +136,13 @@
|
|
|
135
136
|
}}
|
|
136
137
|
/>
|
|
137
138
|
{/key}
|
|
138
|
-
<span class="text-
|
|
139
|
+
<span class="text-muted-foreground">{f.unit}</span>
|
|
139
140
|
{#if f.id === 'scaleX'}
|
|
140
141
|
<button
|
|
141
142
|
type="button"
|
|
142
143
|
aria-label="Keep width and height proportional"
|
|
143
144
|
aria-pressed={view.proportional}
|
|
144
|
-
class={
|
|
145
|
+
class={imageChipClass(view.proportional)}
|
|
145
146
|
onclick={() => {
|
|
146
147
|
tool.proportional = !tool.proportional;
|
|
147
148
|
tick++;
|
|
@@ -150,22 +151,22 @@
|
|
|
150
151
|
</label>
|
|
151
152
|
{/each}
|
|
152
153
|
<label class="flex items-center gap-1">
|
|
153
|
-
<span class="text-
|
|
154
|
+
<span class="text-muted-foreground">Interpolation</span>
|
|
154
155
|
<select
|
|
155
156
|
aria-label="Interpolation"
|
|
156
157
|
value={view.interpolation}
|
|
157
158
|
onchange={(e) => tool.setInterpolation(e.currentTarget.value as Interpolation)}
|
|
158
|
-
class=
|
|
159
|
+
class={imageFieldClass}
|
|
159
160
|
>
|
|
160
161
|
{#each INTERPOLATIONS as i (i)}
|
|
161
162
|
<option value={i}>{i[0].toUpperCase() + i.slice(1)}</option>
|
|
162
163
|
{/each}
|
|
163
164
|
</select>
|
|
164
165
|
</label>
|
|
165
|
-
<button type="button" title="Commit (Enter)" class="px-2 py-1 rounded bg-
|
|
166
|
-
<button type="button" title="Cancel (Esc)" class={
|
|
166
|
+
<button type="button" title="Commit (Enter)" class="px-2 py-1 rounded bg-primary text-primary-foreground hover:bg-primary/90" onclick={() => tool.commit()}>Commit</button>
|
|
167
|
+
<button type="button" title="Cancel (Esc)" class={imageChipClass(false)} onclick={() => tool.cancel()}>Cancel</button>
|
|
167
168
|
{#if view.error}
|
|
168
|
-
<span role="alert" class="text-
|
|
169
|
+
<span role="alert" class="text-destructive">{view.error}</span>
|
|
169
170
|
{/if}
|
|
170
171
|
</div>
|
|
171
172
|
{/if}
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
role="img"
|
|
35
35
|
aria-label={histogram ? `Histogram of ${histogram.samples} pixels` : 'Histogram (no data)'}
|
|
36
36
|
data-testid="image-editor-histogram"
|
|
37
|
-
class="w-full rounded bg-
|
|
37
|
+
class="w-full rounded bg-muted/40 {className}"
|
|
38
38
|
style="height: {height}px"
|
|
39
39
|
>
|
|
40
40
|
{#each paths as p (p.c)}
|