@pixerate/editor-svelte 0.177.0 → 0.178.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.
|
@@ -102,6 +102,13 @@
|
|
|
102
102
|
});
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
+
// Live effect paint plays while the canvas is mounted (idle when nothing is live or it is paused).
|
|
106
|
+
$effect(() => {
|
|
107
|
+
const c = controller;
|
|
108
|
+
const player = untrack(() => c.playEffects());
|
|
109
|
+
return () => player.stop();
|
|
110
|
+
});
|
|
111
|
+
|
|
105
112
|
// Wheel needs a non-passive listener to prevent page scroll (see GOTCHAS).
|
|
106
113
|
$effect(() => {
|
|
107
114
|
const el = viewport;
|
|
@@ -25,8 +25,16 @@
|
|
|
25
25
|
effectPaint: editor.current.effectPaint,
|
|
26
26
|
rendering: editor.current.effectPaintRendering,
|
|
27
27
|
color: editor.current.color,
|
|
28
|
+
animation: controller.getAnimation(),
|
|
29
|
+
playback: editor.current.effectPlayback,
|
|
28
30
|
};
|
|
29
31
|
});
|
|
32
|
+
/** Paints with the effect paint again with some of it changed (the other settings kept). */
|
|
33
|
+
const repaint = (patch: { values?: Record<string, unknown>; map?: unknown; live?: boolean }) => {
|
|
34
|
+
const fx = view.effectPaint;
|
|
35
|
+
if (!fx) return;
|
|
36
|
+
run(() => controller.setEffectPaint({ effect: fx.effect, values: fx.values as never, time: fx.time, map: fx.map, live: fx.live, ...(patch as object) }));
|
|
37
|
+
};
|
|
30
38
|
const thumbnail = $derived.by(() => {
|
|
31
39
|
const { effectPaint, rendering } = view;
|
|
32
40
|
return effectPaint && !rendering ? untrack(() => controller.effectPaintThumbnail(48)) : null;
|
|
@@ -129,9 +137,44 @@
|
|
|
129
137
|
{provider}
|
|
130
138
|
effect={fx.effect}
|
|
131
139
|
values={fx.values}
|
|
132
|
-
onchange={(k, v) =>
|
|
133
|
-
onpreset={(values) =>
|
|
140
|
+
onchange={(k, v) => repaint({ values: { ...fx.values, [k]: v } })}
|
|
141
|
+
onpreset={(values) => repaint({ values: { ...fx.values, ...values } })}
|
|
134
142
|
/>
|
|
143
|
+
<div class="flex flex-wrap items-center gap-2" data-testid="effect-paint-placement">
|
|
144
|
+
<label class="flex items-center gap-1" title="Lay the effect along each stroke instead of fixing it to the canvas">
|
|
145
|
+
<input type="checkbox" checked={Boolean(fx.map)} onchange={(e) => repaint({ map: e.currentTarget.checked ? { by: 'stroke', length: 300, repeat: 'repeat' } : { by: 'canvas' } })} />
|
|
146
|
+
Along the stroke
|
|
147
|
+
</label>
|
|
148
|
+
<label class="flex items-center gap-1" title="Strokes on a stroke layer keep playing the effect">
|
|
149
|
+
<input type="checkbox" checked={Boolean(fx.live)} onchange={(e) => repaint({ live: e.currentTarget.checked })} />
|
|
150
|
+
Live
|
|
151
|
+
</label>
|
|
152
|
+
</div>
|
|
153
|
+
{#if fx.map}
|
|
154
|
+
{@const map = fx.map}
|
|
155
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
156
|
+
<label class="flex items-center gap-1">
|
|
157
|
+
<span class="text-slate-400">Length</span>
|
|
158
|
+
<input type="number" aria-label="Effect length along the stroke" min="16" max="4096" value={map.length} onchange={(e) => { const length = Number(e.currentTarget.value); if (length !== map.length) repaint({ map: { ...map, length } }); }} class="w-16 rounded bg-slate-800 px-1 py-0.5" />
|
|
159
|
+
</label>
|
|
160
|
+
<select aria-label="Effect repeat" value={map.repeat} onchange={(e) => repaint({ map: { ...map, repeat: e.currentTarget.value } })} class="rounded bg-slate-800 px-1 py-0.5">
|
|
161
|
+
<option value="repeat">Repeat</option>
|
|
162
|
+
<option value="mirror">Mirror</option>
|
|
163
|
+
<option value="clamp">Clamp</option>
|
|
164
|
+
</select>
|
|
165
|
+
</div>
|
|
166
|
+
{/if}
|
|
167
|
+
</div>
|
|
168
|
+
{/if}
|
|
169
|
+
{#if view.animation}
|
|
170
|
+
{@const animation = view.animation}
|
|
171
|
+
<div class="flex items-center gap-2 rounded border border-slate-700 p-1" data-effect-part="playback">
|
|
172
|
+
<span class="flex-1 truncate">Live paint: {animation.strokes} {animation.strokes === 1 ? 'stroke' : 'strokes'}</span>
|
|
173
|
+
<button type="button" class={button} aria-pressed={view.playback.playing} onclick={() => attempt(() => controller.setEffectPlayback({ playing: !view.playback.playing }), (m) => (error = m))}>{view.playback.playing ? 'Pause' : 'Play'}</button>
|
|
174
|
+
<label class="flex items-center gap-1">
|
|
175
|
+
<span class="text-slate-400">fps</span>
|
|
176
|
+
<input type="number" aria-label="Live paint frame rate" min="1" max="60" value={view.playback.fps} onchange={(e) => attempt(() => controller.setEffectPlayback({ fps: Math.round(Number(e.currentTarget.value)) }), (m) => (error = m))} class="w-12 rounded bg-slate-800 px-1 py-0.5" />
|
|
177
|
+
</label>
|
|
135
178
|
</div>
|
|
136
179
|
{/if}
|
|
137
180
|
{#if view.layerEffect && view.activeId}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor-svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.178.0",
|
|
4
4
|
"description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
"**/*.css"
|
|
166
166
|
],
|
|
167
167
|
"dependencies": {
|
|
168
|
-
"@pixerate/editor": "0.
|
|
168
|
+
"@pixerate/editor": "0.241.0"
|
|
169
169
|
},
|
|
170
170
|
"peerDependencies": {
|
|
171
171
|
"@dagrejs/dagre": "^1.1.4",
|