@pixerate/editor-svelte 0.116.0 → 0.117.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.
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
handlePaintShortcut,
|
|
17
17
|
pointerPressure,
|
|
18
18
|
FreeTransformTool,
|
|
19
|
+
boxFrameHit,
|
|
20
|
+
boxFrameOverlay,
|
|
19
21
|
getViewportProjection,
|
|
20
22
|
measureCanvasViewport,
|
|
21
23
|
watchCanvasViewport,
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
type SelectionToolOptions,
|
|
27
29
|
type ShapeToolOptions,
|
|
28
30
|
type TextEditSession,
|
|
31
|
+
type TransformOverlay,
|
|
29
32
|
type TypeToolOptions,
|
|
30
33
|
} from '@pixerate/editor/image-editor';
|
|
31
34
|
import { untrack } from 'svelte';
|
|
@@ -343,6 +346,63 @@
|
|
|
343
346
|
return () => window.removeEventListener('keydown', onKey);
|
|
344
347
|
});
|
|
345
348
|
|
|
349
|
+
/** How far outside a frame (in hit tolerances) a drag rotates instead of picking a layer. */
|
|
350
|
+
const ROTATE_BAND = 4;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Transform mode, with no transform open: the active layer's frame, drawn as a transform's.
|
|
354
|
+
* A layer locked in place gets the outline without handles.
|
|
355
|
+
*/
|
|
356
|
+
function layerFrame(): TransformOverlay | null {
|
|
357
|
+
if (mode !== 'transform' || transformTool.active) return null;
|
|
358
|
+
const c = editor.controller;
|
|
359
|
+
const id = c.getState().activeLayerId;
|
|
360
|
+
const layer = id ? c.getLayer(id) : undefined;
|
|
361
|
+
if (!layer || layer.visible === false) return null;
|
|
362
|
+
const bounds = c.getLayerBounds(layer.id);
|
|
363
|
+
if (!bounds) return null;
|
|
364
|
+
return boxFrameOverlay(bounds, !(layer.locks?.all || layer.locks?.position));
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Transform mode: a drag on the active layer's frame transforms it, and a press elsewhere picks
|
|
369
|
+
* the layer there (or none) and drags that. Each drag opens a Free Transform and closes it on
|
|
370
|
+
* release, one undo step when it changed something, so other edits never meet an open one.
|
|
371
|
+
*/
|
|
372
|
+
let frameDrag = false;
|
|
373
|
+
function handleFramePointerDown(e: PointerEvent): boolean {
|
|
374
|
+
if (mode !== 'transform' || transformTool.active || !canvasEl) return false;
|
|
375
|
+
// Middle-button and Space drags pan (see handleMouseDown).
|
|
376
|
+
if (e.button !== 0 || (viewportGestures && isSpacePressed)) return false;
|
|
377
|
+
const c = editor.controller;
|
|
378
|
+
const { pt, tolerance } = transformPoint(e);
|
|
379
|
+
const frame = layerFrame();
|
|
380
|
+
let target = frame && boxFrameHit(frame, pt, tolerance, tolerance * ROTATE_BAND) ? c.getState().activeLayerId : null;
|
|
381
|
+
if (!target) {
|
|
382
|
+
target = c.layerAt(pt);
|
|
383
|
+
c.setActiveLayer(target);
|
|
384
|
+
}
|
|
385
|
+
const layer = target ? c.getLayer(target) : undefined;
|
|
386
|
+
if (!layer || layer.locks?.all || layer.locks?.position) return true;
|
|
387
|
+
e.preventDefault();
|
|
388
|
+
if (transformTool.begin({ layerId: layer.id })) return true;
|
|
389
|
+
try {
|
|
390
|
+
canvasEl.setPointerCapture?.(e.pointerId);
|
|
391
|
+
} catch {
|
|
392
|
+
// Synthetic events have no active pointer to capture.
|
|
393
|
+
}
|
|
394
|
+
transformTool.down(pt, tolerance);
|
|
395
|
+
frameDrag = true;
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
function endFrameDrag(cancelled = false) {
|
|
399
|
+
if (!frameDrag) return;
|
|
400
|
+
frameDrag = false;
|
|
401
|
+
if (!transformTool.active) return;
|
|
402
|
+
if (!cancelled && transformTool.modified) transformTool.commit();
|
|
403
|
+
else transformTool.cancel();
|
|
404
|
+
}
|
|
405
|
+
|
|
346
406
|
/** The document point of a pointer event and the hit tolerance (6 screen px). */
|
|
347
407
|
function transformPoint(e: PointerEvent) {
|
|
348
408
|
const rect = canvasEl!.getBoundingClientRect();
|
|
@@ -448,7 +508,7 @@
|
|
|
448
508
|
mode === 'paint' && brushCursor && editor.controller.getState().activeTool !== 'move' && !transformTool.active
|
|
449
509
|
? { ...brushCursor, diameter: editor.controller.getState().paint.brush.size }
|
|
450
510
|
: null,
|
|
451
|
-
freeTransform: transformTool.overlay(),
|
|
511
|
+
freeTransform: transformTool.overlay() ?? layerFrame(),
|
|
452
512
|
textEdit: typeTool.session?.alive ? typeTool.session.overlay() : null,
|
|
453
513
|
});
|
|
454
514
|
}
|
|
@@ -468,6 +528,7 @@
|
|
|
468
528
|
}
|
|
469
529
|
function handlePaintPointerDown(e: PointerEvent) {
|
|
470
530
|
if (handleTransformPointerDown(e)) return;
|
|
531
|
+
if (handleFramePointerDown(e)) return;
|
|
471
532
|
if (mode !== 'paint' || e.button !== 0 || !canvasEl) return;
|
|
472
533
|
e.preventDefault();
|
|
473
534
|
try {
|
|
@@ -479,6 +540,12 @@
|
|
|
479
540
|
}
|
|
480
541
|
function handlePaintPointerMove(e: PointerEvent) {
|
|
481
542
|
if (handleTransformPointerMove(e)) return;
|
|
543
|
+
if (mode === 'transform' && canvasEl) {
|
|
544
|
+
const { pt, tolerance } = transformPoint(e);
|
|
545
|
+
const frame = layerFrame();
|
|
546
|
+
transformCursor = frame ? transformTool.cursor(boxFrameHit(frame, pt, tolerance, tolerance * ROTATE_BAND)) : 'default';
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
482
549
|
if (mode !== 'paint' || !canvasEl) return;
|
|
483
550
|
const samples = paintSamples(e);
|
|
484
551
|
brushCursor = samples[samples.length - 1] ?? null;
|
|
@@ -486,7 +553,10 @@
|
|
|
486
553
|
else void renderCanvas();
|
|
487
554
|
}
|
|
488
555
|
function handlePaintPointerUp() {
|
|
489
|
-
if (handleTransformPointerUp())
|
|
556
|
+
if (handleTransformPointerUp()) {
|
|
557
|
+
endFrameDrag();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
490
560
|
if (mode !== 'paint' || !paintGesture.active) return;
|
|
491
561
|
paintGesture.up();
|
|
492
562
|
if (paintGesture.error) report('paint', paintGesture.error);
|
|
@@ -552,23 +622,8 @@
|
|
|
552
622
|
return;
|
|
553
623
|
}
|
|
554
624
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const imgPt = canvasToImagePoint(canvasPt, editor.state, view.width, view.height, false);
|
|
558
|
-
const hitLayerId = editor.controller.layerAt(imgPt);
|
|
559
|
-
if (hitLayerId) {
|
|
560
|
-
editor.controller.setActiveLayer(hitLayerId);
|
|
561
|
-
if (!transformTool.active) {
|
|
562
|
-
transformTool.begin();
|
|
563
|
-
}
|
|
564
|
-
} else {
|
|
565
|
-
editor.controller.setActiveLayer(null);
|
|
566
|
-
if (transformTool.active) {
|
|
567
|
-
transformTool.cancel();
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
625
|
+
// Transform mode picks and drags layers on pointerdown (handleFramePointerDown).
|
|
626
|
+
if (mode === 'transform') return;
|
|
572
627
|
|
|
573
628
|
if (transformTool.active) return;
|
|
574
629
|
const canvasPt = getCanvasEventPoint(e);
|
|
@@ -952,10 +1007,13 @@
|
|
|
952
1007
|
onpointerdown={handlePaintPointerDown}
|
|
953
1008
|
onpointermove={handlePaintPointerMove}
|
|
954
1009
|
onpointerup={handlePaintPointerUp}
|
|
955
|
-
onpointercancel={() =>
|
|
1010
|
+
onpointercancel={() => {
|
|
1011
|
+
paintGesture.cancel();
|
|
1012
|
+
endFrameDrag(true);
|
|
1013
|
+
}}
|
|
956
1014
|
data-testid="image-editor-canvas"
|
|
957
|
-
style="width: 100%; height: 100%;{transformActive ? ` cursor: ${transformCursor};` : ''}"
|
|
958
|
-
class="absolute inset-0 w-full h-full block {transformActive ? 'touch-none' : mode === 'paint' ? 'touch-none cursor-crosshair' : mode === 'annotate' && editor.state.activeTool === 'type' ? 'cursor-text' : mode === 'annotate' && editor.state.activeTool === 'shape' ? 'cursor-crosshair' : ''}"
|
|
1015
|
+
style="width: 100%; height: 100%;{transformActive || mode === 'transform' ? ` cursor: ${transformCursor};` : ''}"
|
|
1016
|
+
class="absolute inset-0 w-full h-full block {transformActive || mode === 'transform' ? 'touch-none' : mode === 'paint' ? 'touch-none cursor-crosshair' : mode === 'annotate' && editor.state.activeTool === 'type' ? 'cursor-text' : mode === 'annotate' && editor.state.activeTool === 'shape' ? 'cursor-crosshair' : ''}"
|
|
959
1017
|
></canvas>
|
|
960
1018
|
{#if typeSession}
|
|
961
1019
|
<textarea
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor-svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.117.0",
|
|
4
4
|
"description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"@tiptap/extension-bubble-menu": "^2.27.3",
|
|
161
161
|
"@tiptap/extension-placeholder": "^2.27.3",
|
|
162
162
|
"@tiptap/starter-kit": "^2.27.3",
|
|
163
|
-
"@pixerate/editor": "0.
|
|
163
|
+
"@pixerate/editor": "0.159.0"
|
|
164
164
|
},
|
|
165
165
|
"peerDependencies": {
|
|
166
166
|
"@dagrejs/dagre": "^1.1.4",
|