mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: resolve 41 bugs and wire 21 unimplemented features in image editor
Canvas rendering: - Fix Konva filter application order (filters before cache) - Implement 6 missing filters (motionBlur, radialBlur, surfaceBlur, vignette, grain, sharpen) - Implement exposure, vibrance, warmth adjustments as custom Konva filters - Apply layer blend modes via globalCompositeOperation - Apply object effects (drop shadow, outer glow, stroke) to all shapes - Mount SmartGuidesOverlay during move tool drag - Clip pixel grid to visible viewport (200-line cap for performance) Store logic: - resizeImage now scales all objects proportionally (points, radii, fontSize) - rotate/flip/trim handle line/arrow points arrays and center-based objects - applyCrop creates cropped source image via offscreen canvas - invertSelection creates mask from bounds when no mask exists - cutObjects uses single atomic set() to prevent race conditions - sendToBack respects layer ordering in multi-layer documents - Add batchNudge() and commitHistory() for undoable nudge operations - Add updateLayerThumbnail() method Tool hooks: - Fix clone stamp/dodge/burn perf (toDataURL only on mouseUp, not every move) - Fix magic wand zoom/pixelRatio with explicit stage.toCanvas() viewport - Fix eyedropper sampling with unzoomed canvas export - Fix selection tool stale closure via isDrawingRef - Implement polygonal lasso (click-to-place vertices, double-click to close) - Implement selection subtract mode (geometric and mask-based) - Implement gradient live preview during drag - Fix transform/move tool to persist changes and handle ellipse/polygon/star UI wiring: - Mount rulers and guidelines in editor page - Wire histogram with live canvas imageData - Wire autosave recovery with blob-to-dataURL conversion - Wire fill dialog to Shift+Backspace shortcut - Wire eyedropper and transform options to options bar - Fix history panel undo/redo button reactive state via useSyncExternalStore - Fix layer row name click to select layer (timer-based click/dblclick) - Fix zoom animation coordinate drift with progressive store sync - Fix copy merged to use Konva stage composite export Tests: - 49 new unit tests (store fixes + konva filters) - 8 new E2E test files with 39 test cases
This commit is contained in:
@@ -204,14 +204,49 @@ export function TransformToolTransformer({
|
||||
const handleTransformEnd = useCallback(
|
||||
(e: Konva.KonvaEventObject<Event>) => {
|
||||
const node = e.target;
|
||||
const id = node.id();
|
||||
const scaleX = node.scaleX();
|
||||
const scaleY = node.scaleY();
|
||||
const newW = Math.max(1, node.width() * scaleX);
|
||||
const newH = Math.max(1, node.height() * scaleY);
|
||||
|
||||
// Reset scale on the Konva node
|
||||
node.scaleX(1);
|
||||
node.scaleY(1);
|
||||
node.width(newW);
|
||||
node.height(newH);
|
||||
|
||||
// Directly update the store with the new attributes
|
||||
if (id) {
|
||||
const obj = useEditorStore.getState().objects.find((o) => o.id === id);
|
||||
const newAttrs: Record<string, unknown> = {
|
||||
x: node.x(),
|
||||
y: node.y(),
|
||||
rotation: node.rotation(),
|
||||
};
|
||||
|
||||
if (obj?.type === "ellipse") {
|
||||
// Convert width/height to radiusX/radiusY for ellipses
|
||||
newAttrs.radiusX = newW / 2;
|
||||
newAttrs.radiusY = newH / 2;
|
||||
} else if (obj?.type === "polygon") {
|
||||
// Convert width/height to radius for polygons
|
||||
newAttrs.radius = (newW + newH) / 4;
|
||||
} else if (obj?.type === "star") {
|
||||
// Scale outerRadius and innerRadius proportionally for stars
|
||||
const starAttrs = obj.attrs as { outerRadius: number; innerRadius: number };
|
||||
const avgScale = (Math.abs(scaleX) + Math.abs(scaleY)) / 2;
|
||||
newAttrs.outerRadius = starAttrs.outerRadius * avgScale;
|
||||
newAttrs.innerRadius = starAttrs.innerRadius * avgScale;
|
||||
} else {
|
||||
// Rectangles, images, text: use width/height directly
|
||||
newAttrs.width = newW;
|
||||
newAttrs.height = newH;
|
||||
}
|
||||
|
||||
useEditorStore.getState().updateObject(id, newAttrs);
|
||||
}
|
||||
|
||||
onTransformEnd?.(e);
|
||||
},
|
||||
[onTransformEnd],
|
||||
|
||||
Reference in New Issue
Block a user