@pixerate/editor-svelte 0.167.0 → 0.167.1

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.
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { untrack } from 'svelte';
3
- import { isShapeDescription, type CanvasEffectsController, type ShapeDescription } from '@pixerate/editor/canvas';
3
+ import { canvasEffectStatus, isShapeDescription, type CanvasEffectsController, type ShapeDescription } from '@pixerate/editor/canvas';
4
4
  import type { EffectProvider } from '@pixerate/editor/effects';
5
5
  import EffectsBrowser from '../effects/EffectsBrowser.svelte';
6
6
  import CanvasEffectControls from './CanvasEffectControls.svelte';
@@ -27,6 +27,7 @@
27
27
  let browse = $state<null | 'fill' | 'overlay' | 'transition'>(null);
28
28
  let message = $state<string | null>(null);
29
29
  const nodeEffect = $derived(isShapeDescription(shape) ? shape.effect : undefined);
30
+ const nodeEffectStatus = $derived(nodeEffect && provider ? canvasEffectStatus(nodeEffect, provider) : null);
30
31
  const transition = $derived.by(() => {
31
32
  void tick;
32
33
  return sceneId ? controller.sceneTransition(sceneId) : undefined;
@@ -82,7 +83,9 @@
82
83
  </label>
83
84
  <button type="button" class={btn} aria-label="Remove effect" onclick={() => run(() => controller.removeNodeEffect(id))}>✕</button>
84
85
  </div>
85
- {#if provider}<CanvasEffectControls {controller} nodeId={id} effect={nodeEffect} />{/if}
86
+ {#if nodeEffectStatus && !nodeEffectStatus.ok}
87
+ <p class="text-[11px] text-amber-500" data-canvas-effect-unavailable="">{nodeEffectStatus.reason}</p>
88
+ {:else if provider}<CanvasEffectControls {controller} nodeId={id} effect={nodeEffect} />{/if}
86
89
  </div>
87
90
  {/if}
88
91
  {#if sceneId && transition}
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { untrack } from 'svelte';
3
- import { runCanvasNodeEffect, type CanvasShapeEffect } from '@pixerate/editor/canvas';
3
+ import { CANVAS_EFFECT_MISSING_PATTERN, canvasEffectErrorReason, canvasEffectStatus, runCanvasNodeEffect, type CanvasShapeEffect } from '@pixerate/editor/canvas';
4
4
  import type { EffectProvider } from '@pixerate/editor/effects';
5
5
 
6
6
  interface Props {
@@ -15,11 +15,14 @@
15
15
 
16
16
  let { provider, effect: fx, width, height, clipPath, clipTransform }: Props = $props();
17
17
  let canvas = $state<HTMLCanvasElement | null>(null);
18
- let failed = $state(false);
18
+ let failed = $state<string | null>(null);
19
19
  const dpr = typeof window !== 'undefined' ? Math.min(2, window.devicePixelRatio || 1) : 1;
20
20
  const pw = $derived(Math.max(1, Math.round(width * dpr)));
21
21
  const ph = $derived(Math.max(1, Math.round(height * dpr)));
22
22
  const clipId = `pixerate-effect-clip-${Math.random().toString(36).slice(2)}`;
23
+ const missingId = `pixerate-effect-missing-${Math.random().toString(36).slice(2)}`;
24
+ const status = $derived(canvasEffectStatus(fx, provider));
25
+ const missing = $derived(!status.ok ? status.reason : failed);
23
26
 
24
27
  $effect(() => {
25
28
  const target = canvas;
@@ -27,15 +30,27 @@
27
30
  const e = $state.snapshot(fx) as CanvasShapeEffect;
28
31
  void pw;
29
32
  void ph;
30
- if (!target) return;
31
- failed = false;
32
- const run = untrack(() => runCanvasNodeEffect({ provider: p, effect: e, target, onError: () => (failed = true) }));
33
+ if (!target || !canvasEffectStatus(e, p).ok) return;
34
+ failed = null;
35
+ const run = untrack(() => runCanvasNodeEffect({ provider: p, effect: e, target, onError: (err) => (failed = canvasEffectErrorReason(e, err)) }));
33
36
  return () => run.stop();
34
37
  });
35
38
  </script>
36
39
 
37
- <!-- Draws a shape node's effect: `fill` inside the shape, `overlay` over the whole node. -->
38
- {#if !failed && width > 0 && height > 0}
40
+ <!-- Draws a shape node's effect: `fill` inside the shape, `overlay` over the whole node; a faint hatch with the reason when it cannot be drawn. -->
41
+ {#if missing && width > 0 && height > 0}
42
+ {#if fx.mode === 'overlay' || !clipPath}
43
+ <div role="img" aria-label={missing} title={missing} data-canvas-effect-missing={fx.effect} style="position:absolute;inset:0;pointer-events:none;background:{CANVAS_EFFECT_MISSING_PATTERN}"></div>
44
+ {:else}
45
+ <svg role="img" aria-label={missing} data-canvas-effect-missing={fx.effect} style="position:absolute;inset:0;width:100%;height:100%;pointer-events:none" viewBox="0 0 {width} {height}" preserveAspectRatio="none">
46
+ <title>{missing}</title>
47
+ <defs>
48
+ <pattern id={missingId} width="8" height="8" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="2" height="8" fill="rgba(128,128,128,0.28)" /></pattern>
49
+ </defs>
50
+ <path d={clipPath} transform={clipTransform} fill="url(#{missingId})" />
51
+ </svg>
52
+ {/if}
53
+ {:else if width > 0 && height > 0}
39
54
  {#if fx.mode === 'overlay' || !clipPath}
40
55
  <div style="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;opacity:{fx.opacity ?? 1}">
41
56
  <canvas bind:this={canvas} width={pw} height={ph} style="width:100%;height:100%;display:block" data-canvas-effect={fx.effect}></canvas>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor-svelte",
3
- "version": "0.167.0",
3
+ "version": "0.167.1",
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.227.0"
168
+ "@pixerate/editor": "0.227.1"
169
169
  },
170
170
  "peerDependencies": {
171
171
  "@dagrejs/dagre": "^1.1.4",