@pixerate/editor-svelte 0.166.0 → 0.167.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.
|
@@ -52,6 +52,12 @@
|
|
|
52
52
|
return untrack(() => ({ width: MIXING_PAD_WIDTH, height: MIXING_PAD_HEIGHT, data: controller.mixingPad.pixels() }));
|
|
53
53
|
});
|
|
54
54
|
const R = $derived(wheelSize / 2);
|
|
55
|
+
/** Effect paint shows as a thumbnail of the effect in the paint well. */
|
|
56
|
+
const effectWell = $derived.by(() => {
|
|
57
|
+
const fx = snap.effectPaint;
|
|
58
|
+
const rendering = snap.effectPaintRendering;
|
|
59
|
+
return fx && !rendering ? untrack(() => controller.effectPaintThumbnail(64)) : null;
|
|
60
|
+
});
|
|
55
61
|
const setHsv = (s: number, v: number) => controller.setColor(rgbToHexColor(...hsvToRgb(hsv.h, s, v)));
|
|
56
62
|
const padPoint = (e: PointerEvent) => {
|
|
57
63
|
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
@@ -106,9 +112,10 @@
|
|
|
106
112
|
<div class="flex items-center gap-2" data-testid="paint-source">
|
|
107
113
|
<span
|
|
108
114
|
class="h-5 flex-1 rounded ring-1 ring-slate-700"
|
|
109
|
-
aria-label={snap.paint.type === 'gradient' ? 'Gradient paint' : 'Paint colour'}
|
|
115
|
+
aria-label={snap.effectPaint ? `Effect paint: ${snap.effectPaint.effect}` : snap.paint.type === 'gradient' ? 'Gradient paint' : 'Paint colour'}
|
|
110
116
|
data-testid="paint-well"
|
|
111
|
-
|
|
117
|
+
data-effect-paint={snap.effectPaint ? snap.effectPaint.effect : undefined}
|
|
118
|
+
style:background={effectWell ? `center / cover no-repeat url("${effectWell}")` : paintSourceCss(snap.paint, { paint: color, secondary: snap.secondaryColor })}
|
|
112
119
|
></span>
|
|
113
120
|
<button
|
|
114
121
|
type="button"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { untrack } from 'svelte';
|
|
2
3
|
import { PAPER_EFFECT_BLENDS, type PaintEditorController, type PaperEffectBlend } from '@pixerate/editor/paint-editor';
|
|
3
4
|
import type { EffectUse } from '@pixerate/editor/effects';
|
|
4
5
|
import EffectsBrowser from '../effects/EffectsBrowser.svelte';
|
|
@@ -21,14 +22,22 @@
|
|
|
21
22
|
paper: controller.getPaperEffect(),
|
|
22
23
|
layerEffect: activeId ? controller.getEffectLayer(activeId) : undefined,
|
|
23
24
|
pixel: activeId ? controller.getLayer(activeId)?.type === 'pixel' : false,
|
|
25
|
+
effectPaint: editor.current.effectPaint,
|
|
26
|
+
rendering: editor.current.effectPaintRendering,
|
|
27
|
+
color: editor.current.color,
|
|
24
28
|
};
|
|
25
29
|
});
|
|
26
|
-
|
|
30
|
+
const thumbnail = $derived.by(() => {
|
|
31
|
+
const { effectPaint, rendering } = view;
|
|
32
|
+
return effectPaint && !rendering ? untrack(() => controller.effectPaintThumbnail(48)) : null;
|
|
33
|
+
});
|
|
34
|
+
type Browse = null | 'paper' | 'layer' | 'fill' | 'light' | 'paint';
|
|
27
35
|
const BROWSERS: Record<Exclude<Browse, null>, { uses: EffectUse[]; title: string }> = {
|
|
28
36
|
paper: { uses: ['generator'], title: 'Effect paper' },
|
|
29
37
|
layer: { uses: ['generator', 'overlay', 'title'], title: 'Effect layer' },
|
|
30
38
|
fill: { uses: ['generator', 'overlay', 'title'], title: 'Fill the layer' },
|
|
31
39
|
light: { uses: ['filter'], title: 'Light on the paint' },
|
|
40
|
+
paint: { uses: ['generator', 'overlay', 'title'], title: 'Paint with an effect' },
|
|
32
41
|
};
|
|
33
42
|
let browse = $state<Browse>(null);
|
|
34
43
|
let error = $state<string | null>(null);
|
|
@@ -57,13 +66,15 @@
|
|
|
57
66
|
else if (kind === 'layer') run(() => controller.addEffectLayer(id));
|
|
58
67
|
else if (kind === 'fill') run(() => controller.fillLayerWithEffect(id));
|
|
59
68
|
else if (kind === 'light' && layerId) run(() => controller.applyLightEffect(layerId, id));
|
|
69
|
+
else if (kind === 'paint') run(() => controller.setEffectPaint({ effect: id }));
|
|
60
70
|
}
|
|
61
71
|
</script>
|
|
62
72
|
|
|
63
73
|
<!--
|
|
64
74
|
Provider effects in the paint editor: effect paper (a generator over the sheet, multiplied so the
|
|
65
|
-
grain shows), effect layers, effect fills
|
|
66
|
-
|
|
75
|
+
grain shows), effect layers, effect fills, light baked onto the active layer's dried paint and
|
|
76
|
+
effect paint (brushes take their colours from the effect); plus the controls of the effect
|
|
77
|
+
paper, of an active effect layer and of the effect paint. Each change is one undo
|
|
67
78
|
step (a slider drag is one). Without a provider it says why nothing can be added.
|
|
68
79
|
-->
|
|
69
80
|
<div class={`${panel} ${className}`} data-testid="paint-effects-panel" aria-busy={busy}>
|
|
@@ -73,6 +84,7 @@
|
|
|
73
84
|
<button type="button" class={button} disabled={!provider} aria-pressed={browse === 'layer'} onclick={() => toggle('layer')}>Layer…</button>
|
|
74
85
|
<button type="button" class={button} disabled={!provider || !view.pixel} aria-pressed={browse === 'fill'} onclick={() => toggle('fill')}>Fill…</button>
|
|
75
86
|
<button type="button" class={button} disabled={!provider || !view.pixel} aria-pressed={browse === 'light'} onclick={() => toggle('light')} title="Bake a light, glow or grade into the active layer's dried paint">Light…</button>
|
|
87
|
+
<button type="button" class={button} disabled={!provider} aria-pressed={browse === 'paint'} onclick={() => toggle('paint')} title="Paint with an effect: brushes take each pixel's colour from it">Paint…</button>
|
|
76
88
|
</div>
|
|
77
89
|
{#if !provider}<p class="text-[11px] text-slate-400">No effects provider is registered. Effects in the painting are kept.</p>{/if}
|
|
78
90
|
{#if browse}
|
|
@@ -105,6 +117,23 @@
|
|
|
105
117
|
/>
|
|
106
118
|
</div>
|
|
107
119
|
{/if}
|
|
120
|
+
{#if view.effectPaint}
|
|
121
|
+
{@const fx = view.effectPaint}
|
|
122
|
+
<div class="flex flex-col gap-1 rounded border border-slate-700 p-1" data-effect-part="paint">
|
|
123
|
+
<div class="flex items-center gap-1">
|
|
124
|
+
{#if thumbnail}<img src={thumbnail} alt="" class="h-5 w-8 rounded object-cover ring-1 ring-slate-700" data-testid="effect-paint-thumbnail" />{/if}
|
|
125
|
+
<span class="flex-1 truncate">Paint: {fx.effect}{view.rendering ? ' (rendering…)' : ''}</span>
|
|
126
|
+
<button type="button" class={button} aria-label="Stop painting with the effect" onclick={() => run(() => controller.setColor(view.color))}>✕</button>
|
|
127
|
+
</div>
|
|
128
|
+
<ImageEffectControls
|
|
129
|
+
{provider}
|
|
130
|
+
effect={fx.effect}
|
|
131
|
+
values={fx.values}
|
|
132
|
+
onchange={(k, v) => run(() => controller.setEffectPaint({ effect: fx.effect, values: { ...fx.values, [k]: v as never }, time: fx.time }))}
|
|
133
|
+
onpreset={(values) => run(() => controller.setEffectPaint({ effect: fx.effect, values: { ...fx.values, ...values } as never, time: fx.time }))}
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
{/if}
|
|
108
137
|
{#if view.layerEffect && view.activeId}
|
|
109
138
|
{@const fx = view.layerEffect}
|
|
110
139
|
{@const layerId = view.activeId}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor-svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.167.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.227.0"
|
|
169
169
|
},
|
|
170
170
|
"peerDependencies": {
|
|
171
171
|
"@dagrejs/dagre": "^1.1.4",
|