@pixerate/editor-svelte 0.86.3 → 0.88.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.
Files changed (88) hide show
  1. package/dist/canvas/CanvasDrawLayer.svelte +8 -3
  2. package/dist/canvas/CanvasDrawLayer.svelte.d.ts.map +1 -1
  3. package/dist/canvas/ShapeNode.svelte +57 -1
  4. package/dist/canvas/ShapeNode.svelte.d.ts.map +1 -1
  5. package/dist/canvas/createCanvasAnimation.svelte.d.ts.map +1 -1
  6. package/dist/canvas/createCanvasArrange.svelte.d.ts.map +1 -1
  7. package/dist/canvas/createCanvasAutoLayout.svelte.d.ts.map +1 -1
  8. package/dist/canvas/createCanvasComponents.svelte.d.ts.map +1 -1
  9. package/dist/canvas/createCanvasDraw.svelte.d.ts +6 -2
  10. package/dist/canvas/createCanvasDraw.svelte.d.ts.map +1 -1
  11. package/dist/canvas/createCanvasDraw.svelte.js +5 -1
  12. package/dist/canvas/index.d.ts +2 -1
  13. package/dist/canvas/index.d.ts.map +1 -1
  14. package/dist/canvas/index.js +3 -0
  15. package/dist/canvas/shapeBrushstroke.svelte.d.ts +16 -0
  16. package/dist/canvas/shapeBrushstroke.svelte.d.ts.map +1 -0
  17. package/dist/canvas/shapeBrushstroke.svelte.js +39 -0
  18. package/dist/effects/EffectParameters.svelte +73 -0
  19. package/dist/effects/EffectParameters.svelte.d.ts +25 -0
  20. package/dist/effects/EffectParameters.svelte.d.ts.map +1 -0
  21. package/dist/effects/EffectThumbnail.svelte +48 -0
  22. package/dist/effects/EffectThumbnail.svelte.d.ts +13 -0
  23. package/dist/effects/EffectThumbnail.svelte.d.ts.map +1 -0
  24. package/dist/effects/EffectsBrowser.svelte +112 -0
  25. package/dist/effects/EffectsBrowser.svelte.d.ts +18 -0
  26. package/dist/effects/EffectsBrowser.svelte.d.ts.map +1 -0
  27. package/dist/effects/effects.svelte.d.ts +17 -0
  28. package/dist/effects/effects.svelte.d.ts.map +1 -0
  29. package/dist/effects/effects.svelte.js +49 -0
  30. package/dist/effects/index.d.ts +12 -0
  31. package/dist/effects/index.d.ts.map +1 -0
  32. package/dist/effects/index.js +4 -0
  33. package/dist/image-editor/BrushOptionsBar.svelte +14 -0
  34. package/dist/image-editor/BrushOptionsBar.svelte.d.ts.map +1 -1
  35. package/dist/image-editor/ImageEditor.svelte +15 -0
  36. package/dist/image-editor/ImageEditor.svelte.d.ts +7 -0
  37. package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -1
  38. package/dist/image-editor/ImageEffectControls.svelte +29 -0
  39. package/dist/image-editor/ImageEffectControls.svelte.d.ts +13 -0
  40. package/dist/image-editor/ImageEffectControls.svelte.d.ts.map +1 -0
  41. package/dist/image-editor/ImageProviderEffectsPanel.svelte +129 -0
  42. package/dist/image-editor/ImageProviderEffectsPanel.svelte.d.ts +9 -0
  43. package/dist/image-editor/ImageProviderEffectsPanel.svelte.d.ts.map +1 -0
  44. package/dist/image-editor/PaintGradientEditor.svelte +16 -0
  45. package/dist/image-editor/PaintGradientEditor.svelte.d.ts +15 -0
  46. package/dist/image-editor/PaintGradientEditor.svelte.d.ts.map +1 -0
  47. package/dist/image-editor/imageEditorState.svelte.d.ts +9 -1
  48. package/dist/image-editor/imageEditorState.svelte.d.ts.map +1 -1
  49. package/dist/image-editor/imageEditorState.svelte.js +15 -1
  50. package/dist/image-editor/index.d.ts +4 -0
  51. package/dist/image-editor/index.d.ts.map +1 -1
  52. package/dist/image-editor/index.js +2 -0
  53. package/dist/paint-editor/BrushPanel.svelte +13 -41
  54. package/dist/paint-editor/BrushPanel.svelte.d.ts.map +1 -1
  55. package/dist/paint-editor/ColorPanel.svelte +27 -7
  56. package/dist/paint-editor/ColorPanel.svelte.d.ts.map +1 -1
  57. package/dist/paint-editor/PaintGradientEditor.svelte +16 -0
  58. package/dist/paint-editor/PaintGradientEditor.svelte.d.ts +15 -0
  59. package/dist/paint-editor/PaintGradientEditor.svelte.d.ts.map +1 -0
  60. package/dist/paint-editor/PaintGradientEditorView.svelte +157 -0
  61. package/dist/paint-editor/PaintGradientEditorView.svelte.d.ts +17 -0
  62. package/dist/paint-editor/PaintGradientEditorView.svelte.d.ts.map +1 -0
  63. package/dist/paint-editor/WetPanel.svelte +9 -2
  64. package/dist/paint-editor/WetPanel.svelte.d.ts.map +1 -1
  65. package/dist/paint-editor/index.d.ts +3 -0
  66. package/dist/paint-editor/index.d.ts.map +1 -1
  67. package/dist/paint-editor/index.js +1 -0
  68. package/dist/paint-editor/paintGradientTypes.d.ts +76 -0
  69. package/dist/paint-editor/paintGradientTypes.d.ts.map +1 -0
  70. package/dist/paint-editor/paintGradientTypes.js +8 -0
  71. package/dist/video-editor/ClipInspector.svelte +10 -3
  72. package/dist/video-editor/ClipInspector.svelte.d.ts.map +1 -1
  73. package/dist/video-editor/EffectControls.svelte +32 -0
  74. package/dist/video-editor/EffectControls.svelte.d.ts +15 -0
  75. package/dist/video-editor/EffectControls.svelte.d.ts.map +1 -0
  76. package/dist/video-editor/VideoEditor.svelte +18 -2
  77. package/dist/video-editor/VideoEditor.svelte.d.ts +9 -0
  78. package/dist/video-editor/VideoEditor.svelte.d.ts.map +1 -1
  79. package/dist/video-editor/VideoEffectsPanel.svelte +154 -0
  80. package/dist/video-editor/VideoEffectsPanel.svelte.d.ts +9 -0
  81. package/dist/video-editor/VideoEffectsPanel.svelte.d.ts.map +1 -0
  82. package/dist/video-editor/createVideoEditor.svelte.d.ts +8 -1
  83. package/dist/video-editor/createVideoEditor.svelte.d.ts.map +1 -1
  84. package/dist/video-editor/createVideoEditor.svelte.js +15 -1
  85. package/dist/video-editor/index.d.ts +3 -0
  86. package/dist/video-editor/index.d.ts.map +1 -1
  87. package/dist/video-editor/index.js +1 -0
  88. package/package.json +7 -2
@@ -13,7 +13,9 @@ import type BrushOptionsBarComponent from "./BrushOptionsBar.svelte";
13
13
  import type FreeTransformOptionsBarComponent from "./FreeTransformOptionsBar.svelte";
14
14
  import type ShapeOptionsBarComponent from "./ShapeOptionsBar.svelte";
15
15
  import type TypeOptionsBarComponent from "./TypeOptionsBar.svelte";
16
+ import type ImageProviderEffectsPanelComponent from "./ImageProviderEffectsPanel.svelte";
16
17
  export { default as ImageEditor } from './ImageEditor.svelte';
18
+ export { default as PaintGradientEditor } from './PaintGradientEditor.svelte';
17
19
  export { default as Histogram } from './Histogram.svelte';
18
20
  export { default as AdjustmentLayersPanel } from './AdjustmentLayersPanel.svelte';
19
21
  export { default as CurvesEditor } from './CurvesEditor.svelte';
@@ -27,6 +29,7 @@ export { default as BrushOptionsBar } from './BrushOptionsBar.svelte';
27
29
  export { default as FreeTransformOptionsBar } from './FreeTransformOptionsBar.svelte';
28
30
  export { default as ShapeOptionsBar } from './ShapeOptionsBar.svelte';
29
31
  export { default as TypeOptionsBar } from './TypeOptionsBar.svelte';
32
+ export { default as ImageProviderEffectsPanel } from './ImageProviderEffectsPanel.svelte';
30
33
  export * from './imageEditorState.svelte.js';
31
34
  export type ImageEditorProps = ComponentProps<typeof ImageEditorComponent>;
32
35
  export type HistogramProps = ComponentProps<typeof HistogramComponent>;
@@ -42,5 +45,6 @@ export type BrushOptionsBarProps = ComponentProps<typeof BrushOptionsBarComponen
42
45
  export type FreeTransformOptionsBarProps = ComponentProps<typeof FreeTransformOptionsBarComponent>;
43
46
  export type ShapeOptionsBarProps = ComponentProps<typeof ShapeOptionsBarComponent>;
44
47
  export type TypeOptionsBarProps = ComponentProps<typeof TypeOptionsBarComponent>;
48
+ export type ImageProviderEffectsPanelProps = ComponentProps<typeof ImageProviderEffectsPanelComponent>;
45
49
  export { applyRegionMosaic, applyRegionBlur, resolveMosaicRegionBounds, type MosaicRegion, type MosaicImageDataLike } from '@pixerate/editor/image-editor';
46
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image-editor/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image-editor/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export { default as ImageEditor } from './ImageEditor.svelte';
2
+ export { default as PaintGradientEditor } from './PaintGradientEditor.svelte';
2
3
  export { default as Histogram } from './Histogram.svelte';
3
4
  export { default as AdjustmentLayersPanel } from './AdjustmentLayersPanel.svelte';
4
5
  export { default as CurvesEditor } from './CurvesEditor.svelte';
@@ -12,5 +13,6 @@ export { default as BrushOptionsBar } from './BrushOptionsBar.svelte';
12
13
  export { default as FreeTransformOptionsBar } from './FreeTransformOptionsBar.svelte';
13
14
  export { default as ShapeOptionsBar } from './ShapeOptionsBar.svelte';
14
15
  export { default as TypeOptionsBar } from './TypeOptionsBar.svelte';
16
+ export { default as ImageProviderEffectsPanel } from './ImageProviderEffectsPanel.svelte';
15
17
  export * from './imageEditorState.svelte.js';
16
18
  export { applyRegionMosaic, applyRegionBlur, resolveMosaicRegionBounds } from '@pixerate/editor/image-editor';
@@ -6,7 +6,7 @@
6
6
  brushEngineControls,
7
7
  brushLoadColor,
8
8
  downloadBytes,
9
- multiColorSliders,
9
+ brushTakesPaint,
10
10
  patchBrushValue,
11
11
  patchPath,
12
12
  readPath,
@@ -30,13 +30,14 @@
30
30
  type BlendMode,
31
31
  type BrushRotation,
32
32
  type WetTool,
33
- type MultiColorMode,
34
33
  type PaintEditorController,
35
34
  } from '@pixerate/editor/paint-editor';
36
35
  import { untrack } from 'svelte';
37
36
  import PaintSlider from './PaintSlider.svelte';
38
37
  import PixelCanvas from './PixelCanvas.svelte';
39
- import { attempt, button, paintEditorState, panel } from './paintEditorRune.svelte.js';
38
+ import { DEFAULT_PAINT_GRADIENT } from '@pixerate/editor/paint-editor';
39
+ import PaintGradientEditor from './PaintGradientEditor.svelte';
40
+ import { attempt, button, chip, paintEditorState, panel } from './paintEditorRune.svelte.js';
40
41
 
41
42
  interface Props {
42
43
  controller: PaintEditorController;
@@ -62,14 +63,12 @@
62
63
  return untrack(() => new Map(list.map((b) => [b.id, controller.brushThumbnail(b.id, { width: thumbnailWidth, height: thumbnailHeight, color: '#26324a' })])));
63
64
  });
64
65
  const engine = $derived(brushEngineControls(brush));
65
- const mc = $derived(brush.behavior.multicolor);
66
66
  const carried = $derived(brushLoadColor(snap.mixerLoad));
67
67
  const mixingValue = $derived(engine?.mixingPath === 'blender.mixing' ? brush.blender.mixing : engine?.mixingPath === 'smudge.mixing' ? brush.smudge.mixing : brush.behavior.mixing);
68
- const setColors = (colors: string[]) => controller.setBrush({ behavior: { multicolor: { colors } } });
69
68
  const slug = (name: string) => name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 60) || 'brush';
70
69
  </script>
71
70
 
72
- <!-- The brush library with thumbnails, the active brush's settings and blend, its engine's controls (blender, smudge, pick-up / mix, mixing, dirty, multi-colour, load), save, import and export. -->
71
+ <!-- The brush library with thumbnails, the active brush's settings and blend, its engine's controls (blender, smudge, pick-up / mix, mixing, dirty, brush gradient, load), save, import and export. -->
73
72
  <div class={`${panel} ${className}`} data-testid="brush-panel">
74
73
  <div class="grid grid-cols-2 gap-1" role="listbox" aria-label="Brushes">
75
74
  {#each snap.brushes as b (b.id)}
@@ -188,41 +187,14 @@
188
187
  <input type="checkbox" aria-label="Dirty brush" checked={brush.behavior.dirty} onchange={(e) => controller.setBrush({ behavior: { dirty: e.currentTarget.checked } })} /> Dirty brush
189
188
  </label>
190
189
  {/if}
191
- {#if engine.multicolor}
192
- <div class="flex flex-col gap-1.5" data-testid="multicolor">
193
- <label class="flex items-center justify-between gap-2">
194
- <span class="text-slate-400">Multi-colour</span>
195
- <select aria-label="Multi-colour" value={mc.mode} onchange={(e) => controller.setBrush({ behavior: { multicolor: { mode: e.currentTarget.value as MultiColorMode } } })} class="rounded bg-slate-800 px-1 py-0.5">
196
- <option value="off">Off</option>
197
- <option value="tip">Across the tip</option>
198
- <option value="dab">Per dab</option>
199
- </select>
200
- </label>
201
- {#if mc.mode !== 'off'}
202
- <div class="flex flex-wrap items-center gap-1" aria-label="Multi-colour colours">
203
- {#each mc.colors as col, i (i)}
204
- <span class="flex items-center">
205
- <input type="color" aria-label={`Multi-colour ${i + 1}`} value={col} onchange={(e) => setColors(mc.colors.map((x, j) => (j === i ? e.currentTarget.value : x)))} class="h-5 w-6 rounded bg-transparent" />
206
- <button type="button" aria-label={`Remove multi-colour ${i + 1}`} class="px-0.5 text-slate-500 hover:text-white" onclick={() => setColors(mc.colors.filter((_, j) => j !== i))}>×</button>
207
- </span>
208
- {/each}
209
- {#if mc.colors.length < 8}
210
- <button type="button" class={button} aria-label="Add multi-colour" onclick={() => setColors([...(mc.colors.length ? mc.colors : [snap.color, snap.secondaryColor]), snap.color].slice(0, 8))}>+</button>
211
- {/if}
212
- {#if mc.colors.length < 2}<span class="text-[10px] text-slate-500">Uses the paint and second colours</span>{/if}
213
- </div>
214
- {#if mc.mode === 'dab'}
215
- <label class="flex items-center justify-between gap-2">
216
- <span class="text-slate-400">Order</span>
217
- <select aria-label="Colour order" value={mc.order} onchange={(e) => controller.setBrush({ behavior: { multicolor: { order: e.currentTarget.value as 'sequence' | 'random' } } })} class="rounded bg-slate-800 px-1 py-0.5">
218
- <option value="sequence">In order</option>
219
- <option value="random">Random</option>
220
- </select>
221
- </label>
222
- {/if}
223
- {#each multiColorSliders(mc.mode) as c (c.path)}
224
- <PaintSlider control={c} value={readPath(brush, c.path)} onchange={(v) => controller.setBrush(patchPath(brush as never, c.path, v) as never)} />
225
- {/each}
190
+ {#if brushTakesPaint(brush)}
191
+ <div class="flex flex-col gap-1.5" data-testid="brush-gradient">
192
+ <div class="flex items-center justify-between gap-2">
193
+ <span class="text-slate-400" title="A gradient of the brush's own, used instead of the paint (the multi-colour brush)">Brush gradient</span>
194
+ <button type="button" aria-pressed={brush.paint !== null} class={chip(brush.paint !== null)} onclick={() => run(() => controller.setBrush({ paint: brush.paint ? null : DEFAULT_PAINT_GRADIENT }))}>{brush.paint ? 'On' : 'Off'}</button>
195
+ </div>
196
+ {#if brush.paint}
197
+ <PaintGradientEditor value={brush.paint} colors={{ paint: snap.color, secondary: snap.secondaryColor }} onchange={(g) => run(() => controller.setBrush({ paint: g }))} />
226
198
  {/if}
227
199
  </div>
228
200
  {/if}
@@ -1 +1 @@
1
- {"version":3,"file":"BrushPanel.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/BrushPanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAgCH,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAOvC,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAoNH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"BrushPanel.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/BrushPanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EA+BH,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AASvC,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyLH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -18,6 +18,8 @@
18
18
  type PaintEditorController,
19
19
  } from '@pixerate/editor/paint-editor';
20
20
  import { untrack } from 'svelte';
21
+ import { DEFAULT_PAINT_GRADIENT, paintSourceCss } from '@pixerate/editor/paint-editor';
22
+ import PaintGradientEditor from './PaintGradientEditor.svelte';
21
23
  import PixelCanvas from './PixelCanvas.svelte';
22
24
  import { attempt, button, chip, paintEditorState, panel } from './paintEditorRune.svelte.js';
23
25
 
@@ -59,7 +61,7 @@
59
61
  };
60
62
  </script>
61
63
 
62
- <!-- Hue wheel with harmonies, saturation and value, colours, harmony chips, swatches, mixing pad (paint, knife, pick with a sample size, measured mixes, kept pads). -->
64
+ <!-- Hue wheel with harmonies, saturation and value, colours, gradient paint, harmony chips, swatches (colours and gradients), mixing pad (paint, knife, pick with a sample size, measured mixes, kept pads). -->
63
65
  <div class={`${panel} ${className}`} data-testid="color-panel">
64
66
  <div class="relative self-center" style={`width: ${wheelSize}px; height: ${wheelSize}px`}>
65
67
  <div
@@ -101,6 +103,24 @@
101
103
  />
102
104
  {/key}
103
105
  </div>
106
+ <div class="flex items-center gap-2" data-testid="paint-source">
107
+ <span
108
+ class="h-5 flex-1 rounded ring-1 ring-slate-700"
109
+ aria-label={snap.paint.type === 'gradient' ? 'Gradient paint' : 'Paint colour'}
110
+ data-testid="paint-well"
111
+ style:background={paintSourceCss(snap.paint, { paint: color, secondary: snap.secondaryColor })}
112
+ ></span>
113
+ <button
114
+ type="button"
115
+ class={chip(snap.paint.type === 'gradient')}
116
+ aria-pressed={snap.paint.type === 'gradient'}
117
+ title="Paint that changes colour as the stroke goes"
118
+ onclick={() => run(() => (snap.paint.type === 'gradient' ? controller.setColor(color) : controller.setPaint(DEFAULT_PAINT_GRADIENT)))}>Gradient</button
119
+ >
120
+ </div>
121
+ {#if snap.paint.type === 'gradient'}
122
+ <PaintGradientEditor value={snap.paint} colors={{ paint: color, secondary: snap.secondaryColor }} onchange={(g) => run(() => controller.setPaint(g))} />
123
+ {/if}
104
124
  <label class="flex items-center gap-2">
105
125
  <span class="w-16 text-slate-400">Saturation</span>
106
126
  <input type="range" aria-label="Saturation" min="0" max="1" step="0.01" value={hsv.s} oninput={(e) => setHsv(Number(e.currentTarget.value), hsv.v)} class="flex-1 accent-indigo-500" />
@@ -129,19 +149,19 @@
129
149
  <button
130
150
  type="button"
131
151
  role="option"
132
- aria-selected={s.color === color}
133
- aria-label={s.name ?? s.color}
134
- title={`${s.name ?? s.color} (right-click to remove)`}
152
+ aria-selected={s.paint ? snap.paint === s.paint : snap.paint.type === 'color' && s.color === color}
153
+ aria-label={s.name ?? (s.paint ? 'Gradient' : s.color)}
154
+ title={`${s.name ?? (s.paint ? 'Gradient' : s.color)} (right-click to remove)`}
135
155
  class="h-5 w-5 rounded ring-1 ring-slate-700"
136
- style={`background: ${s.color}`}
137
- onclick={() => controller.setColor(s.color)}
156
+ style:background={s.paint ? paintSourceCss(s.paint, { paint: color, secondary: snap.secondaryColor }) : s.color}
157
+ onclick={() => run(() => (s.paint ? controller.setPaint(s.paint) : controller.setColor(s.color)))}
138
158
  oncontextmenu={(e) => {
139
159
  e.preventDefault();
140
160
  controller.removeSwatch(i);
141
161
  }}
142
162
  ></button>
143
163
  {/each}
144
- <button type="button" class={button} aria-label="Add swatch" onclick={() => controller.addSwatch(color)}>+</button>
164
+ <button type="button" class={button} aria-label="Add swatch" onclick={() => run(() => controller.addSwatch(snap.paint))}>+</button>
145
165
  </div>
146
166
  {#if mixingPad}
147
167
  <div class="flex flex-col gap-1" data-testid="mixing-pad">
@@ -1 +1 @@
1
- {"version":3,"file":"ColorPanel.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/ColorPanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAgBH,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAMvC,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA6KH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ColorPanel.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/ColorPanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAgBH,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAQvC,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsLH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { PAINT_GRADIENT_KIT, type PaintGradientSource } from '@pixerate/editor/paint-editor';
3
+ import PaintGradientEditorView from './PaintGradientEditorView.svelte';
4
+
5
+ interface Props {
6
+ value: PaintGradientSource;
7
+ onchange: (paint: PaintGradientSource) => void;
8
+ /** What `paint` / `secondary` stops show as (the editor's two colours). */
9
+ colors: { paint: string; secondary: string };
10
+ class?: string;
11
+ }
12
+ let { value, onchange, colors, class: className = '' }: Props = $props();
13
+ </script>
14
+
15
+ <!-- The gradient paint editor (see PaintGradientEditorView). -->
16
+ <PaintGradientEditorView {value} {onchange} {colors} class={className} kit={PAINT_GRADIENT_KIT} />
@@ -0,0 +1,15 @@
1
+ import { type PaintGradientSource } from '@pixerate/editor/paint-editor';
2
+ interface Props {
3
+ value: PaintGradientSource;
4
+ onchange: (paint: PaintGradientSource) => void;
5
+ /** What `paint` / `secondary` stops show as (the editor's two colours). */
6
+ colors: {
7
+ paint: string;
8
+ secondary: string;
9
+ };
10
+ class?: string;
11
+ }
12
+ declare const PaintGradientEditor: import("svelte").Component<Props, {}, "">;
13
+ type PaintGradientEditor = ReturnType<typeof PaintGradientEditor>;
14
+ export default PaintGradientEditor;
15
+ //# sourceMappingURL=PaintGradientEditor.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PaintGradientEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/PaintGradientEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAI3F,UAAU,KAAK;IACb,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC/C,2EAA2E;IAC3E,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaH,QAAA,MAAM,mBAAmB,2CAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,157 @@
1
+ <script lang="ts">
2
+ import type { Gradient as PaintGradientSource, GradientKit as PaintGradientKit, GradientMappingKind as PaintGradientMappingKind, GradientRepeat as PaintGradientRepeat, GradientSpace as PaintGradientSpace, GradientStop as PaintGradientStop } from './paintGradientTypes.js';
3
+
4
+ interface Props {
5
+ value: PaintGradientSource;
6
+ onchange: (paint: PaintGradientSource) => void;
7
+ /** What `paint` / `secondary` stops show as (the editor's two colours). */
8
+ colors: { paint: string; secondary: string };
9
+ class?: string;
10
+ /** The gradient helpers (`PAINT_GRADIENT_KIT`, from the editor's own entry). */
11
+ kit: PaintGradientKit;
12
+ }
13
+ let { value, onchange, colors, class: className = '', kit }: Props = $props();
14
+ // The kit is a constant module object: reading it once is right.
15
+ // svelte-ignore state_referenced_locally
16
+ const {
17
+ PAINT_GRADIENT_MAPPINGS,
18
+ PAINT_GRADIENT_MAPPING_LABELS,
19
+ PAINT_GRADIENT_PRESETS,
20
+ PAINT_GRADIENT_REPEATS,
21
+ PAINT_GRADIENT_REPEAT_LABELS,
22
+ PAINT_GRADIENT_SPACES,
23
+ PAINT_GRADIENT_SPACE_LABELS,
24
+ addPaintGradientStop,
25
+ paintGradientMappingFor,
26
+ paintSourceCss,
27
+ removePaintGradientStop,
28
+ reversePaintGradient,
29
+ updatePaintGradientStop,
30
+ } = kit;
31
+ let selected = $state(0);
32
+ const sel = $derived(Math.min(selected, value.stops.length - 1));
33
+ const stop = $derived(value.stops[sel]);
34
+ const map = $derived(value.map);
35
+ const button = 'px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-200 hover:bg-slate-700 disabled:opacity-40';
36
+ const select = 'rounded bg-slate-800 px-1 py-0.5 text-[11px]';
37
+ const number = 'w-16 rounded bg-slate-800 px-1 py-0.5 text-[11px]';
38
+ const pct = (v: number) => Math.round(v * 1000) / 10;
39
+ const stopHex = (c: string) => (c === 'paint' ? colors.paint : c === 'secondary' ? colors.secondary : c);
40
+ const own = (c: string) => c !== 'paint' && c !== 'secondary';
41
+ const patchStop = (patch: Partial<PaintGradientStop>) => {
42
+ const r = updatePaintGradientStop(value, sel, patch);
43
+ selected = r.index;
44
+ onchange(r.paint);
45
+ };
46
+ const setMap = (m: Record<string, unknown>) => onchange({ ...value, map: { ...map, ...m } as PaintGradientSource['map'] });
47
+ const addAt = (e: MouseEvent) => {
48
+ const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
49
+ const r = addPaintGradientStop(value, rect.width ? (e.clientX - rect.left) / rect.width : 0.5, colors);
50
+ if (r.index >= 0) {
51
+ selected = r.index;
52
+ onchange(r.paint);
53
+ }
54
+ };
55
+ </script>
56
+
57
+ <!-- Gradient paint editor (the vector editor's stop ramp, for paint): stops (colour or the paint / second colour, opacity, position, midpoint), mixing space, what moves the stroke along it, softness, reverse and presets. -->
58
+ <div class={`flex flex-col gap-1.5 text-xs text-slate-200 ${className}`} data-testid="paint-gradient-editor" aria-label="Gradient paint">
59
+ <div class="flex items-center gap-1">
60
+ <select
61
+ aria-label="Gradient preset"
62
+ class={select}
63
+ value=""
64
+ onchange={(e) => {
65
+ const v = e.currentTarget.value;
66
+ if (v) {
67
+ selected = 0;
68
+ onchange(PAINT_GRADIENT_PRESETS[Number(v)].paint);
69
+ }
70
+ }}
71
+ >
72
+ <option value="">Presets…</option>
73
+ {#each PAINT_GRADIENT_PRESETS as p, i (p.name)}<option value={i}>{p.name}</option>{/each}
74
+ </select>
75
+ <button type="button" class={button} onclick={() => onchange(reversePaintGradient(value))}>Reverse</button>
76
+ </div>
77
+ <div
78
+ role="slider"
79
+ tabindex="0"
80
+ aria-label="Gradient ramp: click to add a stop"
81
+ aria-valuemin={0}
82
+ aria-valuemax={100}
83
+ aria-valuenow={pct(stop.offset)}
84
+ data-testid="paint-gradient-ramp"
85
+ class="relative h-6 cursor-copy rounded ring-1 ring-slate-700"
86
+ style:background={paintSourceCss(value, colors)}
87
+ onclick={addAt}
88
+ onkeydown={() => {}}
89
+ ></div>
90
+ <div class="relative h-4" aria-label="Stops">
91
+ {#each value.stops as s, i (i)}
92
+ <button
93
+ type="button"
94
+ aria-label={`Stop ${i + 1} at ${pct(s.offset)}%`}
95
+ aria-pressed={i === sel}
96
+ class={`absolute top-0 h-4 w-3 -translate-x-1/2 rounded-sm ring-1 ${i === sel ? 'ring-white' : 'ring-slate-600'}`}
97
+ style:left={`${s.offset * 100}%`}
98
+ style:background={stopHex(s.color)}
99
+ onclick={() => (selected = i)}
100
+ ></button>
101
+ {/each}
102
+ </div>
103
+ <div class="flex flex-wrap items-center gap-1" data-testid="paint-gradient-stop">
104
+ <select aria-label="Stop colour source" class={select} value={own(stop.color) ? 'color' : stop.color} onchange={(e) => patchStop({ color: e.currentTarget.value === 'color' ? stopHex(stop.color) : e.currentTarget.value })}>
105
+ <option value="color">Colour</option>
106
+ <option value="paint">Paint colour</option>
107
+ <option value="secondary">Second colour</option>
108
+ </select>
109
+ {#if own(stop.color)}
110
+ <input type="color" aria-label="Stop colour" value={stop.color} oninput={(e) => patchStop({ color: e.currentTarget.value })} class="h-6 w-8 rounded bg-transparent" />
111
+ {/if}
112
+ <label class="flex items-center gap-1">At <input type="number" aria-label="Stop position" min="0" max="100" step="1" value={pct(stop.offset)} oninput={(e) => patchStop({ offset: Number(e.currentTarget.value) / 100 })} class={number} />%</label>
113
+ <label class="flex items-center gap-1">Opacity <input type="number" aria-label="Stop opacity" min="0" max="100" step="5" value={pct(stop.opacity ?? 1)} oninput={(e) => patchStop({ opacity: Number(e.currentTarget.value) / 100 })} class={number} />%</label>
114
+ {#if sel < value.stops.length - 1}
115
+ <label class="flex items-center gap-1">Midpoint <input type="number" aria-label="Stop midpoint" min="5" max="95" step="1" value={pct(stop.midpoint ?? 0.5)} oninput={(e) => patchStop({ midpoint: Number(e.currentTarget.value) / 100 })} class={number} />%</label>
116
+ {/if}
117
+ <button
118
+ type="button"
119
+ class={button}
120
+ disabled={value.stops.length <= 2}
121
+ onclick={() => {
122
+ const at = sel;
123
+ selected = Math.max(0, at - 1);
124
+ onchange(removePaintGradientStop(value, at));
125
+ }}>Remove stop</button
126
+ >
127
+ </div>
128
+ <div class="flex flex-wrap items-center gap-1" data-testid="paint-gradient-mapping">
129
+ <select aria-label="Gradient follows" class={select} value={map.by} onchange={(e) => onchange({ ...value, map: paintGradientMappingFor(e.currentTarget.value as PaintGradientMappingKind, map) })}>
130
+ {#each PAINT_GRADIENT_MAPPINGS as m (m)}<option value={m}>{PAINT_GRADIENT_MAPPING_LABELS[m]}</option>{/each}
131
+ </select>
132
+ {#if map.by === 'distance'}
133
+ <input type="number" aria-label="Gradient length" min="1" max="100000" value={map.length} oninput={(e) => setMap({ length: Math.max(1, Number(e.currentTarget.value) || 1) })} class={number} />
134
+ <select aria-label="Gradient length unit" class={select} value={map.unit ?? 'px'} onchange={(e) => setMap({ unit: e.currentTarget.value })}>
135
+ <option value="px">px</option>
136
+ <option value="dabs">dabs</option>
137
+ </select>
138
+ {/if}
139
+ {#if map.by === 'time'}
140
+ <input type="number" aria-label="Gradient duration" min="1" max="600000" value={map.duration} oninput={(e) => setMap({ duration: Math.max(1, Number(e.currentTarget.value) || 1) })} class={number} />
141
+ {/if}
142
+ {#if map.by === 'random'}
143
+ <input type="number" aria-label="Dabs per pick" min="1" max="500" value={map.every ?? 1} oninput={(e) => setMap({ every: Math.max(1, Math.round(Number(e.currentTarget.value) || 1)) })} class={number} />
144
+ {/if}
145
+ {#if map.by === 'distance' || map.by === 'time'}
146
+ <select aria-label="Gradient repeat" class={select} value={map.repeat ?? 'clamp'} onchange={(e) => setMap({ repeat: e.currentTarget.value as PaintGradientRepeat })}>
147
+ {#each PAINT_GRADIENT_REPEATS as r (r)}<option value={r}>{PAINT_GRADIENT_REPEAT_LABELS[r]}</option>{/each}
148
+ </select>
149
+ {/if}
150
+ </div>
151
+ <div class="flex items-center gap-1">
152
+ <select aria-label="Gradient mixing" class={select} value={value.space} onchange={(e) => onchange({ ...value, space: e.currentTarget.value as PaintGradientSpace })}>
153
+ {#each PAINT_GRADIENT_SPACES as s (s)}<option value={s}>{PAINT_GRADIENT_SPACE_LABELS[s]}</option>{/each}
154
+ </select>
155
+ <label class="flex flex-1 items-center gap-1">Softness <input type="range" aria-label="Gradient softness" min="0" max="1" step="0.05" value={value.softness ?? 1} oninput={(e) => onchange({ ...value, softness: Number(e.currentTarget.value) })} class="flex-1 accent-indigo-500" /></label>
156
+ </div>
157
+ </div>
@@ -0,0 +1,17 @@
1
+ import type { Gradient as PaintGradientSource, GradientKit as PaintGradientKit } from './paintGradientTypes.js';
2
+ interface Props {
3
+ value: PaintGradientSource;
4
+ onchange: (paint: PaintGradientSource) => void;
5
+ /** What `paint` / `secondary` stops show as (the editor's two colours). */
6
+ colors: {
7
+ paint: string;
8
+ secondary: string;
9
+ };
10
+ class?: string;
11
+ /** The gradient helpers (`PAINT_GRADIENT_KIT`, from the editor's own entry). */
12
+ kit: PaintGradientKit;
13
+ }
14
+ declare const PaintGradientEditorView: import("svelte").Component<Props, {}, "">;
15
+ type PaintGradientEditorView = ReturnType<typeof PaintGradientEditorView>;
16
+ export default PaintGradientEditorView;
17
+ //# sourceMappingURL=PaintGradientEditorView.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PaintGradientEditorView.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/PaintGradientEditorView.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,IAAI,mBAAmB,EAAE,WAAW,IAAI,gBAAgB,EAAkK,MAAM,yBAAyB,CAAC;AAG9Q,UAAU,KAAK;IACb,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC/C,2EAA2E;IAC3E,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,GAAG,EAAE,gBAAgB,CAAC;CACvB;AA0HH,QAAA,MAAM,uBAAuB,2CAAwC,CAAC;AACtE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC1E,eAAe,uBAAuB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { WET_FLOW_KINDS, WET_PARAM_SLIDERS, WET_SPEED_SLIDER, WET_TILT_SLIDERS, readPath, type PaintEditorController, type WetFlowKind } from '@pixerate/editor/paint-editor';
2
+ import { WET_FLOW_KINDS, WET_GPU_OPTIONS, WET_PARAM_SLIDERS, WET_SPEED_SLIDER, WET_TILT_SLIDERS, readPath, wetEngineSummary, type PaintEditorController, type WetFlowKind, type WetGpuMode } from '@pixerate/editor/paint-editor';
3
3
  import PaintSlider from './PaintSlider.svelte';
4
4
  import { attempt, button, chip, paintEditorState, panel } from './paintEditorRune.svelte.js';
5
5
 
@@ -24,7 +24,7 @@
24
24
  const FLOW_LABELS: Record<WetFlowKind, string> = { none: 'None', linear: 'One way', swirl: 'Swirl', radial: 'Outwards', turbulent: 'Eddies' };
25
25
  </script>
26
26
 
27
- <!-- Wet media: status, Dry now, Pause, the water overlay, speed, Wet paper, tilt, the active layer's wet settings and flow map, and the kernel in use. -->
27
+ <!-- Wet media: status, Dry now, Pause, the water overlay, speed, Wet paper, tilt, the active layer's wet settings and flow map, the kernel in use, and Engine B (the WebGPU accelerator) with a switch to force the CPU. -->
28
28
  <div class={`${panel} ${className}`} data-testid="wet-panel">
29
29
  <div class="flex items-center justify-between">
30
30
  <span class={wet.wet ? 'text-sky-300' : 'text-slate-400'} data-testid="wet-status">{wet.wet ? (wet.paused ? 'Wet (paused)' : 'Wet') : 'Dry'}</span>
@@ -62,5 +62,12 @@
62
62
  {#if backend.backend}
63
63
  <p class="text-[10px] text-slate-500">{backend.backend.kind === 'wasm-threads' ? `WebAssembly, ${backend.backend.threads} threads` : backend.backend.kind === 'wasm' ? 'WebAssembly, one thread' : 'JavaScript'}</p>
64
64
  {/if}
65
+ <label class="flex items-center justify-between gap-2">
66
+ <span class="text-slate-400">Engine</span>
67
+ <select aria-label="Wet engine" value={wet.gpu} onchange={(e) => run(() => controller.setWetEngine({ gpu: (e.currentTarget as HTMLSelectElement).value as WetGpuMode }))} class="rounded bg-slate-800 px-1 py-0.5">
68
+ {#each WET_GPU_OPTIONS as o (o.value)}<option value={o.value}>{o.label}</option>{/each}
69
+ </select>
70
+ </label>
71
+ <p class={`text-[10px] ${backend.engine.state === 'active' ? 'text-emerald-300' : 'text-slate-500'}`} data-testid="wet-engine">{wetEngineSummary(backend.engine)}</p>
65
72
  {#if error}<p role="alert" class="text-[11px] text-rose-400">{error}</p>{/if}
66
73
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"WetPanel.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/WetPanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmF,KAAK,qBAAqB,EAAoB,MAAM,+BAA+B,CAAC;AAK5K,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkEH,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"WetPanel.svelte.d.ts","sourceRoot":"","sources":["../../src/paint-editor/WetPanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsH,KAAK,qBAAqB,EAAqC,MAAM,+BAA+B,CAAC;AAKhO,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyEH,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -8,6 +8,7 @@ import type ColorPanelComponent from './ColorPanel.svelte';
8
8
  import type PaintLayersPanelComponent from './PaintLayersPanel.svelte';
9
9
  import type WetPanelComponent from './WetPanel.svelte';
10
10
  import type StickerPanelComponent from './StickerPanel.svelte';
11
+ import type PaintGradientEditorComponent from './PaintGradientEditor.svelte';
11
12
  export { default as PaintEditor } from './PaintEditor.svelte';
12
13
  export { default as PaintCanvas } from './PaintCanvas.svelte';
13
14
  export { default as PaintToolbar } from './PaintToolbar.svelte';
@@ -17,6 +18,7 @@ export { default as ColorPanel } from './ColorPanel.svelte';
17
18
  export { default as PaintLayersPanel } from './PaintLayersPanel.svelte';
18
19
  export { default as WetPanel } from './WetPanel.svelte';
19
20
  export { default as StickerPanel } from './StickerPanel.svelte';
21
+ export { default as PaintGradientEditor } from './PaintGradientEditor.svelte';
20
22
  export { default as PaintSlider } from './PaintSlider.svelte';
21
23
  export { default as PaintPresenceLayer } from './PaintPresenceLayer.svelte';
22
24
  export { createPaintDirector, createReactivePaintEditor, paintEditorState } from './paintEditorRune.svelte.js';
@@ -29,4 +31,5 @@ export type ColorPanelProps = ComponentProps<typeof ColorPanelComponent>;
29
31
  export type PaintLayersPanelProps = ComponentProps<typeof PaintLayersPanelComponent>;
30
32
  export type WetPanelProps = ComponentProps<typeof WetPanelComponent>;
31
33
  export type StickerPanelProps = ComponentProps<typeof StickerPanelComponent>;
34
+ export type PaintGradientEditorProps = ComponentProps<typeof PaintGradientEditorComponent>;
32
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/paint-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,yBAAyB,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,iBAAiB,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/G,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,OAAO,yBAAyB,CAAC,CAAC;AACrF,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/paint-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,yBAAyB,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,iBAAiB,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,4BAA4B,MAAM,8BAA8B,CAAC;AAE7E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/G,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,OAAO,yBAAyB,CAAC,CAAC;AACrF,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE7E,MAAM,MAAM,wBAAwB,GAAG,cAAc,CAAC,OAAO,4BAA4B,CAAC,CAAC"}
@@ -7,6 +7,7 @@ export { default as ColorPanel } from './ColorPanel.svelte';
7
7
  export { default as PaintLayersPanel } from './PaintLayersPanel.svelte';
8
8
  export { default as WetPanel } from './WetPanel.svelte';
9
9
  export { default as StickerPanel } from './StickerPanel.svelte';
10
+ export { default as PaintGradientEditor } from './PaintGradientEditor.svelte';
10
11
  export { default as PaintSlider } from './PaintSlider.svelte';
11
12
  export { default as PaintPresenceLayer } from './PaintPresenceLayer.svelte';
12
13
  export { createPaintDirector, createReactivePaintEditor, paintEditorState } from './paintEditorRune.svelte.js';
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Gradient paint types for `PaintGradientEditorView`, written out here so the view imports nothing
3
+ * from a core entry: it is shared by the paint editor and image editor entries, each of which may
4
+ * import only its own (`tests/entry-isolation.test.ts`; Svelte ships its components as source).
5
+ * They copy `@pixerate/editor/paint`'s shapes; the wrappers pass core-typed values in, so
6
+ * svelte-check fails if the two drift apart.
7
+ */
8
+ export interface GradientStop {
9
+ offset: number;
10
+ color: string;
11
+ opacity?: number;
12
+ midpoint?: number;
13
+ }
14
+ export type GradientRepeat = 'clamp' | 'repeat' | 'mirror';
15
+ export type GradientSpace = 'pigment' | 'oklab' | 'srgb';
16
+ export type GradientMapping = {
17
+ by: 'distance';
18
+ length: number;
19
+ repeat: GradientRepeat;
20
+ unit?: 'px' | 'dabs';
21
+ } | {
22
+ by: 'pressure';
23
+ } | {
24
+ by: 'tilt';
25
+ } | {
26
+ by: 'velocity';
27
+ } | {
28
+ by: 'direction';
29
+ } | {
30
+ by: 'time';
31
+ duration: number;
32
+ repeat?: GradientRepeat;
33
+ } | {
34
+ by: 'across-tip';
35
+ } | {
36
+ by: 'random';
37
+ every?: number;
38
+ };
39
+ export type GradientMappingKind = GradientMapping['by'];
40
+ export interface Gradient {
41
+ type: 'gradient';
42
+ stops: GradientStop[];
43
+ space: GradientSpace;
44
+ map: GradientMapping;
45
+ softness?: number;
46
+ }
47
+ export type GradientColors = {
48
+ paint: string;
49
+ secondary: string;
50
+ };
51
+ /** The `PAINT_GRADIENT_KIT` the view uses. */
52
+ export interface GradientKit {
53
+ readonly PAINT_GRADIENT_MAPPINGS: readonly GradientMappingKind[];
54
+ readonly PAINT_GRADIENT_MAPPING_LABELS: Readonly<Record<GradientMappingKind, string>>;
55
+ readonly PAINT_GRADIENT_PRESETS: readonly {
56
+ name: string;
57
+ paint: Gradient;
58
+ }[];
59
+ readonly PAINT_GRADIENT_REPEATS: readonly GradientRepeat[];
60
+ readonly PAINT_GRADIENT_REPEAT_LABELS: Readonly<Record<GradientRepeat, string>>;
61
+ readonly PAINT_GRADIENT_SPACES: readonly GradientSpace[];
62
+ readonly PAINT_GRADIENT_SPACE_LABELS: Readonly<Record<GradientSpace, string>>;
63
+ addPaintGradientStop(g: Gradient, offset: number, colors?: GradientColors): {
64
+ paint: Gradient;
65
+ index: number;
66
+ };
67
+ paintGradientMappingFor(by: GradientMappingKind, current: GradientMapping): GradientMapping;
68
+ paintSourceCss(s: Gradient, colors?: GradientColors): string;
69
+ removePaintGradientStop(g: Gradient, index: number): Gradient;
70
+ reversePaintGradient(g: Gradient): Gradient;
71
+ updatePaintGradientStop(g: Gradient, index: number, patch: Partial<GradientStop>): {
72
+ paint: Gradient;
73
+ index: number;
74
+ };
75
+ }
76
+ //# sourceMappingURL=paintGradientTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paintGradientTypes.d.ts","sourceRoot":"","sources":["../../src/paint-editor/paintGradientTypes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Gradient paint types for `PaintGradientEditorView`, written out here so the view imports nothing
3
+ * from a core entry: it is shared by the paint editor and image editor entries, each of which may
4
+ * import only its own (`tests/entry-isolation.test.ts`; Svelte ships its components as source).
5
+ * They copy `@pixerate/editor/paint`'s shapes; the wrappers pass core-typed values in, so
6
+ * svelte-check fails if the two drift apart.
7
+ */
8
+ export {};