@pixerate/editor-svelte 0.31.0 → 0.33.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.
@@ -1 +1 @@
1
- {"version":3,"file":"createCanvasAnimation.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasAnimation.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,KAAK,EACV,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,4BAA4B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU;IAClF,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,mDAAmD;IACnD,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAChC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC3C,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,4BAA4B,CAAC,KAAK,CAAC;;;;;;;;;;kBA2DnG,KAAK,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAa65lH,CAAC;;;;;;;;;;;YAAg/C,CAAC;mBAA8B,CAAC;;;;;;;YAAmjB,CAAC;gBAA0B,CAAC;;;EAHzhqH;AAED,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,IAAI,UAAU,CAAC,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"createCanvasAnimation.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasAnimation.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,KAAK,EACV,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,4BAA4B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU;IAClF,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,mDAAmD;IACnD,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAChC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC3C,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,4BAA4B,CAAC,KAAK,CAAC;;;;;;;;;;kBA2DnG,KAAK,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAag1mH,CAAC;;;;;;;;;;;YAAg/C,CAAC;mBAA8B,CAAC;;;;;;;YAAmjB,CAAC;gBAA0B,CAAC;;;EAH58qH;AAED,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,IAAI,UAAU,CAAC,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"createCanvasAutoLayout.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasAutoLayout.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,iCAAiC,EACtC,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,KAAK,WAAW,GAAG,iCAAiC,CAAC,GAAG,CAAC,CAAC;AAE1D,MAAM,WAAW,6BAA6B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,CACnF,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,gBAAgB,CAAC;IACrE,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,6BAA6B,CAAC,KAAK,CAAC;;;IA+BzH,2FAA2F;kBAC7E,OAAO,SAAS,kBAAkB,WAAW,OAAO,EAAE,GAAG,OAAO,EAAE;IAKhF,gFAAgF;0BAC1D,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAIjE,4EAA4E;iBAC/D,MAAM;IAInB;;;OAGG;wBACiB,MAAM;;;;;;;;aAiBm//E,CAAC;;;;aAAiX,CAAC;cAAwB,CAAC;;;;;;;;;;gBAAqrD,CAAC;;;;EAHhlkF;AAED,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,IAAI,UAAU,CAAC,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"createCanvasAutoLayout.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasAutoLayout.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,iCAAiC,EACtC,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,KAAK,WAAW,GAAG,iCAAiC,CAAC,GAAG,CAAC,CAAC;AAE1D,MAAM,WAAW,6BAA6B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,CACnF,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,gBAAgB,CAAC;IACrE,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,6BAA6B,CAAC,KAAK,CAAC;;;IA+BzH,2FAA2F;kBAC7E,OAAO,SAAS,kBAAkB,WAAW,OAAO,EAAE,GAAG,OAAO,EAAE;IAKhF,gFAAgF;0BAC1D,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAIjE,4EAA4E;iBAC/D,MAAM;IAInB;;;OAGG;wBACiB,MAAM;;;;;;;;aAiBs6gF,CAAC;;;;aAAiX,CAAC;cAAwB,CAAC;;;;;;;;;;gBAAqrD,CAAC;;;;EAHnglF;AAED,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,IAAI,UAAU,CAAC,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"createCanvasComponents.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasComponents.svelte.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,iCAAiC,EACtC,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,KAAK,WAAW,GAAG,iCAAiC,CAAC,GAAG,CAAC,CAAC;AAE1D,MAAM,WAAW,6BAA6B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,CACnF,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IAC/D,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,oFAAoF;IACpF,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,6BAA6B,CAAC,KAAK,CAAC;IAazH,gCAAgC;;;;;4BASmh8I,CAAC;;UAAmM,CAAC;YAAsB,CAAC;eAAyB,CAAC;;8BAA8E,CAAC;;;;;;;;;;6BAA4nC,CAAC;;;;;;;;eAA6yB,CAAC;;;;;;;oBAAi7B,CAAC;;;;;;;;;;;;;;gBAA07C,CAAC;;EAHjplJ;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"createCanvasComponents.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasComponents.svelte.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,iCAAiC,EACtC,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,KAAK,WAAW,GAAG,iCAAiC,CAAC,GAAG,CAAC,CAAC;AAE1D,MAAM,WAAW,6BAA6B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,CACnF,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IAC/D,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,oFAAoF;IACpF,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,6BAA6B,CAAC,KAAK,CAAC;IAazH,gCAAgC;;;;;4BASs88I,CAAC;;UAAmM,CAAC;YAAsB,CAAC;eAAyB,CAAC;;8BAA8E,CAAC;;;;;;;;;;6BAA4nC,CAAC;;;;;;;;eAA6yB,CAAC;;;;;;;oBAAi7B,CAAC;;;;;;;;;;;;;;gBAA07C,CAAC;;EAHpkmJ;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -218,9 +218,40 @@
218
218
  <circle data-vector-anchor={a.ref.index} cx={a.x} cy={a.y} r={size / 2} fill={a.selected ? accentColor : THEME.handleFill} stroke={accentColor} />
219
219
  {/if}
220
220
  {/each}
221
+ {#each overlay.cornerWidgets as w (`corner:${anchorKey(w)}`)}
222
+ <g data-vector-corner-widget={w.ref.index} data-corner-kind={w.kind}>
223
+ <circle cx={w.x} cy={w.y} r={THEME.cornerWidgetRadius + (w.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />
224
+ <circle cx={w.x} cy={w.y} r={1.5} fill={accentColor} />
225
+ </g>
226
+ {/each}
221
227
  {#if closing}
222
228
  <circle cx={closing.x} cy={closing.y} r={as} stroke={accentColor} />
223
229
  {/if}
230
+ {#if overlay.toolStroke}
231
+ <path
232
+ data-vector-tool-stroke={overlay.toolStroke.tool}
233
+ d={overlay.toolStroke.d}
234
+ stroke={overlay.toolStroke.tool === 'eraser' ? THEME.eraserFill : accentColor}
235
+ stroke-width={overlay.toolStroke.tool === 'eraser' ? overlay.toolStroke.width : 1}
236
+ stroke-linecap="round"
237
+ stroke-linejoin="round"
238
+ stroke-dasharray={overlay.toolStroke.tool === 'knife' ? '5 3' : undefined}
239
+ />
240
+ {/if}
241
+ {#if overlay.pencilString}
242
+ <line
243
+ data-vector-pencil-string=""
244
+ x1={overlay.pencilString.x1}
245
+ y1={overlay.pencilString.y1}
246
+ x2={overlay.pencilString.x2}
247
+ y2={overlay.pencilString.y2}
248
+ stroke={accentColor}
249
+ stroke-dasharray="2 2"
250
+ />
251
+ {/if}
252
+ {#if overlay.cutPoint}
253
+ <circle data-vector-cut-point="" cx={overlay.cutPoint.x} cy={overlay.cutPoint.y} r={THEME.handleRadius + 1} fill={THEME.handleFill} stroke={accentColor} />
254
+ {/if}
224
255
  {#if overlay.marquee}
225
256
  <rect
226
257
  data-vector-marquee=""
@@ -1 +1 @@
1
- {"version":3,"file":"VectorCanvas.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorCanvas.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,EAOH,KAAK,sBAAsB,EAC5B,MAAM,yBAAyB,CAAC;AAMjC,UAAU,KAAK;IACb,UAAU,EAAE,sBAAsB,CAAC;IACnC,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAsLH,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"VectorCanvas.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorCanvas.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,EAOH,KAAK,sBAAsB,EAC5B,MAAM,yBAAyB,CAAC;AAMjC,UAAU,KAAK;IACb,UAAU,EAAE,sBAAsB,CAAC;IACnC,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAqMH,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -14,6 +14,39 @@
14
14
  <g data-vector-id={node.id} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>
15
15
  <Self nodes={node.children} />
16
16
  </g>
17
+ {:else if node.strokeParts}
18
+ {@const sp = node.strokeParts}
19
+ <!-- An aligned stroke (double width, clipped or masked by the shape) or one with arrowheads. -->
20
+ <g data-vector-id={node.id} data-vector-stroke-align={sp.align} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>
21
+ {#if sp.clip}
22
+ <defs>
23
+ {#if sp.clip.kind === 'clip'}
24
+ <clipPath id={sp.clip.id}><path d={node.d} clip-rule={node.fillRule} /></clipPath>
25
+ {:else}
26
+ <mask id={sp.clip.id} maskUnits="userSpaceOnUse" x={sp.clip.bounds.x} y={sp.clip.bounds.y} width={sp.clip.bounds.width} height={sp.clip.bounds.height}>
27
+ <rect x={sp.clip.bounds.x} y={sp.clip.bounds.y} width={sp.clip.bounds.width} height={sp.clip.bounds.height} fill="#fff" />
28
+ <path d={node.d} fill="#000" fill-rule={node.fillRule} />
29
+ </mask>
30
+ {/if}
31
+ </defs>
32
+ {/if}
33
+ <path data-vector-part="fill" d={node.d} fill={node.fill} fill-rule={node.fillRule} stroke="none" />
34
+ <path
35
+ data-vector-part="stroke"
36
+ d={sp.d}
37
+ fill="none"
38
+ stroke={node.stroke}
39
+ stroke-width={sp.width}
40
+ stroke-linecap={node.strokeLinecap as any}
41
+ stroke-linejoin={node.strokeLinejoin as any}
42
+ stroke-dasharray={node.strokeDasharray}
43
+ clip-path={sp.clip?.kind === 'clip' ? `url(#${sp.clip.id})` : undefined}
44
+ mask={sp.clip?.kind === 'mask' ? `url(#${sp.clip.id})` : undefined}
45
+ />
46
+ {#each sp.heads as head, i (i)}
47
+ <path data-vector-part="head" d={head} fill={node.stroke} />
48
+ {/each}
49
+ </g>
17
50
  {:else}
18
51
  <path
19
52
  data-vector-id={node.id}
@@ -1 +1 @@
1
- {"version":3,"file":"VectorSceneNodes.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorSceneNodes.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAI9D,UAAU,KAAK;IACb,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACpC;AAqBH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"VectorSceneNodes.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorSceneNodes.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAI9D,UAAU,KAAK;IACb,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACpC;AA2CH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -1,5 +1,16 @@
1
1
  <script lang="ts">
2
- import { getVectorSelectionStyle, vectorPaintToHex, type VectorEditorController } from '@pixerate/editor/vector';
2
+ import {
3
+ VECTOR_ARROWHEADS,
4
+ VECTOR_ARROWHEAD_LABELS,
5
+ VECTOR_CORNER_KINDS,
6
+ VECTOR_CORNER_KIND_LABELS,
7
+ VECTOR_STROKE_ALIGN_LABELS,
8
+ getVectorSelectionStyle,
9
+ vectorPaintToHex,
10
+ type VectorCornerKind,
11
+ type VectorEditorController,
12
+ type VectorStrokeAlign
13
+ } from '@pixerate/editor/vector';
3
14
  import { vectorStateOf } from './subscribe.svelte.js';
4
15
 
5
16
  interface Props {
@@ -12,9 +23,39 @@
12
23
  const store = vectorStateOf(() => controller);
13
24
  const view = $derived(store.current);
14
25
  const style = $derived(getVectorSelectionStyle(view));
15
- const source = $derived(
16
- style ?? { fill: view.defaults.fill ?? null, stroke: view.defaults.stroke ?? null, strokeWidth: view.defaults.strokeWidth ?? 1, opacity: 1 }
17
- );
26
+ const source = $derived.by(() => {
27
+ if (style) return style;
28
+ const d = view.defaults;
29
+ return {
30
+ fill: d.fill ?? null,
31
+ stroke: d.stroke ?? null,
32
+ strokeWidth: d.strokeWidth ?? 1,
33
+ opacity: 1,
34
+ strokeAlign: d.strokeAlign ?? 'center',
35
+ startArrow: d.startArrow ?? null,
36
+ endArrow: d.endArrow ?? null,
37
+ arrowAlign: d.arrowAlign ?? 'extend',
38
+ startArrowScale: d.startArrowScale ?? 1,
39
+ endArrowScale: d.endArrowScale ?? 1,
40
+ cornerRadius: d.cornerRadius,
41
+ cornerKind: d.cornerKind ?? 'round',
42
+ corners: 1,
43
+ hasOpenPath: true
44
+ };
45
+ });
46
+ const aligns = Object.keys(VECTOR_STROKE_ALIGN_LABELS) as VectorStrokeAlign[];
47
+ const ends = [
48
+ { end: 'start', key: 'startArrow', scaleKey: 'startArrowScale', label: 'Start' },
49
+ { end: 'end', key: 'endArrow', scaleKey: 'endArrowScale', label: 'End' }
50
+ ] as const;
51
+ const selectClass = 'h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs';
52
+ const numberClass = 'h-7 w-16 rounded border border-border bg-background px-1.5 text-xs';
53
+
54
+ function setCorners(patch: { radius?: number; kind?: VectorCornerKind }) {
55
+ if (!style) controller.setDefaults({ ...(patch.radius !== undefined ? { cornerRadius: patch.radius } : {}), ...(patch.kind ? { cornerKind: patch.kind } : {}) });
56
+ else if (patch.radius !== undefined) controller.setCornerRadius(patch.radius);
57
+ else if (patch.kind) controller.setCornerKind(patch.kind);
58
+ }
18
59
 
19
60
  function apply(patch: Record<string, unknown>) {
20
61
  if (style) controller.setStyle(patch);
@@ -65,6 +106,67 @@
65
106
  }}
66
107
  />
67
108
  </label>
109
+ <label class="flex items-center gap-2 text-xs text-foreground" data-vector-style="strokeAlign">
110
+ <span class="w-16">Align</span>
111
+ <select aria-label="Stroke alignment" class={selectClass} value={source.strokeAlign} onchange={(e) => apply({ strokeAlign: e.currentTarget.value })}>
112
+ {#each aligns as a (a)}<option value={a}>{VECTOR_STROKE_ALIGN_LABELS[a]}</option>{/each}
113
+ </select>
114
+ {#if style?.mixed.strokeAlign}<span class="text-[11px] text-muted-foreground">Mixed</span>{/if}
115
+ </label>
116
+ {#if source.hasOpenPath}
117
+ {#each ends as { key, scaleKey, label } (key)}
118
+ <div class="flex items-center gap-2" data-vector-style={key}>
119
+ <span class="w-16 text-xs text-foreground">{label}</span>
120
+ <select aria-label="{label} arrowhead" class={selectClass} value={source[key] ?? ''} onchange={(e) => apply({ [key]: e.currentTarget.value || null })}>
121
+ <option value="">None</option>
122
+ {#each VECTOR_ARROWHEADS as h (h)}<option value={h}>{VECTOR_ARROWHEAD_LABELS[h]}</option>{/each}
123
+ </select>
124
+ <input
125
+ type="number"
126
+ min="0.1"
127
+ step="0.25"
128
+ aria-label="{label} arrowhead scale"
129
+ title="Scale (× stroke width)"
130
+ class={numberClass}
131
+ value={source[scaleKey]}
132
+ oninput={(e) => {
133
+ const n = parseFloat(e.currentTarget.value);
134
+ if (Number.isFinite(n) && n > 0) apply({ [scaleKey]: n });
135
+ }}
136
+ />
137
+ </div>
138
+ {/each}
139
+ {#if source.startArrow || source.endArrow}
140
+ <label class="flex items-center gap-2 text-xs text-foreground" data-vector-style="arrowAlign">
141
+ <span class="w-16">Heads</span>
142
+ <select aria-label="Arrowhead alignment" class={selectClass} value={source.arrowAlign} onchange={(e) => apply({ arrowAlign: e.currentTarget.value })}>
143
+ <option value="extend">Tip past end</option>
144
+ <option value="tip">Tip at end</option>
145
+ </select>
146
+ </label>
147
+ {/if}
148
+ {/if}
149
+ {#if source.corners > 0}
150
+ <div class="flex items-center gap-2" data-vector-style="corners">
151
+ <span class="w-16 text-xs text-foreground">Corners</span>
152
+ <input
153
+ type="number"
154
+ min="0"
155
+ step="1"
156
+ aria-label="Corner radius"
157
+ class={numberClass}
158
+ value={Math.round(source.cornerRadius * 100) / 100}
159
+ oninput={(e) => {
160
+ const n = parseFloat(e.currentTarget.value);
161
+ if (Number.isFinite(n) && n >= 0) setCorners({ radius: n });
162
+ }}
163
+ />
164
+ <select aria-label="Corner kind" class={selectClass} value={source.cornerKind} onchange={(e) => setCorners({ kind: e.currentTarget.value as VectorCornerKind })}>
165
+ {#each VECTOR_CORNER_KINDS as k (k)}<option value={k}>{VECTOR_CORNER_KIND_LABELS[k]}</option>{/each}
166
+ </select>
167
+ {#if style?.mixed.cornerRadius}<span class="text-[11px] text-muted-foreground">Mixed</span>{/if}
168
+ </div>
169
+ {/if}
68
170
  {#if style}
69
171
  <label class="flex items-center gap-2 text-xs text-foreground">
70
172
  <span class="w-16">Opacity</span>
@@ -1 +1 @@
1
- {"version":3,"file":"VectorStylePanel.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorStylePanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAA6C,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAI/G,UAAU,KAAK;IACb,UAAU,EAAE,sBAAsB,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2DH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"VectorStylePanel.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorStylePanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EASH,KAAK,sBAAsB,EAE5B,MAAM,yBAAyB,CAAC;AAIjC,UAAU,KAAK;IACb,UAAU,EAAE,sBAAsB,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqIH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -3,6 +3,8 @@
3
3
  VECTOR_TOOLS,
4
4
  VECTOR_TOOL_GLYPHS,
5
5
  VECTOR_TOOL_SHORTCUTS,
6
+ VECTOR_EDIT_TOGGLES,
7
+ VECTOR_PATH_ACTIONS,
6
8
  vectorToolLabel,
7
9
  type VectorEditorController,
8
10
  type VectorTool
@@ -20,10 +22,16 @@
20
22
  showArrange?: boolean;
21
23
  /** The snapping toggle (default `true`). */
22
24
  showSnap?: boolean;
25
+ /**
26
+ * Path editing: Join, Average, Cut at Points, Remove Redundant Points, Smooth, the Keep
27
+ * Shape / Curvature / Shapes toggles, and the pencil smoothing and eraser size inputs while
28
+ * those tools are active (default `true`).
29
+ */
30
+ showPathEdit?: boolean;
23
31
  class?: string;
24
32
  }
25
33
 
26
- let { controller, tools = VECTOR_TOOLS, showHistory = true, showArrange = true, showSnap = true, class: className = '' }: Props = $props();
34
+ let { controller, tools = VECTOR_TOOLS, showHistory = true, showArrange = true, showSnap = true, showPathEdit = true, class: className = '' }: Props = $props();
27
35
 
28
36
  const snapTitle = 'Snap to objects';
29
37
  const modKey = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform ?? '') ? '⌘' : 'Ctrl';
@@ -31,6 +39,7 @@
31
39
  const store = vectorStateOf(() => controller);
32
40
  const view = $derived(store.current);
33
41
  const count = $derived(view.selection.length);
42
+ const points = $derived(view.tool === 'direct' ? view.selectedAnchors.length : 0);
34
43
  const groupSelected = $derived(view.selection.some((id) => controller.getNode(id)?.type === 'group'));
35
44
 
36
45
  const combine = $derived([
@@ -96,6 +105,68 @@
96
105
  </button>
97
106
  </div>
98
107
  {/if}
108
+ {#if showPathEdit}
109
+ <div class="ml-1 flex items-center gap-1" role="group" aria-label="Path editing">
110
+ {#each VECTOR_PATH_ACTIONS as a (a.id)}
111
+ <button
112
+ type="button"
113
+ data-vector-path-action={a.id}
114
+ class={vectorButtonClass}
115
+ title={a.shortcut ? `${a.title} (${modKey}+${a.shortcut})` : a.title}
116
+ aria-label={a.title}
117
+ disabled={!a.enabled(count, points)}
118
+ onclick={() => void a.run(controller)}
119
+ >
120
+ {a.label}
121
+ </button>
122
+ {/each}
123
+ {#each VECTOR_EDIT_TOGGLES as t (t.key)}
124
+ <button
125
+ type="button"
126
+ data-vector-edit={t.key}
127
+ class={vectorButtonClass}
128
+ aria-pressed={view.editing[t.key]}
129
+ title={t.title}
130
+ aria-label={t.title}
131
+ onclick={() => controller.setEditing({ [t.key]: !view.editing[t.key] })}
132
+ >
133
+ {t.label}
134
+ </button>
135
+ {/each}
136
+ {#if view.tool === 'pencil'}
137
+ <label class="flex items-center gap-1 text-xs text-foreground">
138
+ Smoothing
139
+ <input
140
+ type="range"
141
+ min="0"
142
+ max="1"
143
+ step="0.05"
144
+ aria-label="Pencil smoothing"
145
+ class="h-4 w-20 accent-primary"
146
+ value={view.editing.pencilSmoothing}
147
+ oninput={(e) => controller.setEditing({ pencilSmoothing: parseFloat(e.currentTarget.value) })}
148
+ />
149
+ </label>
150
+ {/if}
151
+ {#if view.tool === 'eraser'}
152
+ <label class="flex items-center gap-1 text-xs text-foreground">
153
+ Size
154
+ <input
155
+ type="number"
156
+ min="0.5"
157
+ step="1"
158
+ aria-label="Eraser size"
159
+ class="h-7 w-16 rounded border border-border bg-background px-1.5 text-xs"
160
+ value={view.editing.eraserSize}
161
+ oninput={(e) => {
162
+ const n = parseFloat(e.currentTarget.value);
163
+ if (Number.isFinite(n) && n > 0) controller.setEditing({ eraserSize: n });
164
+ }}
165
+ />
166
+ </label>
167
+ {/if}
168
+ </div>
169
+ {/if}
99
170
  {#if showArrange}
100
171
  <div class="ml-1 flex items-center gap-1" role="group" aria-label="Combine">
101
172
  {#each combine as item (item.title)}{@render action(item)}{/each}
@@ -9,6 +9,12 @@ interface Props {
9
9
  showArrange?: boolean;
10
10
  /** The snapping toggle (default `true`). */
11
11
  showSnap?: boolean;
12
+ /**
13
+ * Path editing: Join, Average, Cut at Points, Remove Redundant Points, Smooth, the Keep
14
+ * Shape / Curvature / Shapes toggles, and the pencil smoothing and eraser size inputs while
15
+ * those tools are active (default `true`).
16
+ */
17
+ showPathEdit?: boolean;
12
18
  class?: string;
13
19
  }
14
20
  declare const VectorToolbar: import("svelte").Component<Props, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"VectorToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorToolbar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAKH,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EAChB,MAAM,yBAAyB,CAAC;AAKjC,UAAU,KAAK;IACb,UAAU,EAAE,sBAAsB,CAAC;IACnC,oCAAoC;IACpC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4EH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"VectorToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/vector/VectorToolbar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAOH,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EAChB,MAAM,yBAAyB,CAAC;AAKjC,UAAU,KAAK;IACb,UAAU,EAAE,sBAAsB,CAAC;IACnC,oCAAoC;IACpC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA0GH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor-svelte",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -107,7 +107,7 @@
107
107
  "@tiptap/extension-bubble-menu": "^2.11.5",
108
108
  "@tiptap/extension-placeholder": "^2.11.5",
109
109
  "@tiptap/starter-kit": "^2.11.5",
110
- "@pixerate/editor": "0.34.0"
110
+ "@pixerate/editor": "0.36.0"
111
111
  },
112
112
  "peerDependencies": {
113
113
  "@dagrejs/dagre": "^1.1.4",