@mhamz.01/easyflow-whiteboard 2.4.0 → 2.5.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":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qBAAqB,CAAC,EAAE,YAAY,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAaD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,KAAK,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,UAAc,EACd,cAA+B,EAC/B,YAAmB,EACnB,qBAA0B,EAC1B,YAAY,GACb,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qBAAqB,CAAC,EAAE,YAAY,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAaD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,KAAK,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,UAAc,EACd,cAA+B,EAC/B,YAAmB,EACnB,qBAA0B,EAC1B,YAAY,GACb,EAAE,uBAAuB,2CAiezB"}
|
|
@@ -183,60 +183,33 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
183
183
|
itemsToDrag = [itemId];
|
|
184
184
|
setSelectedIds(new Set([itemId]));
|
|
185
185
|
}
|
|
186
|
-
// ── Read VPT first — single source of truth for coordinate space ──
|
|
187
|
-
const vpt = fabricCanvas?.current?.viewportTransform;
|
|
188
|
-
const liveZoom = vpt ? vpt[0] : 1;
|
|
189
|
-
const liveVpX = vpt ? vpt[4] : 0;
|
|
190
|
-
const liveVpY = vpt ? vpt[5] : 0;
|
|
191
|
-
// ── Snapshot world positions from DOM directly ──
|
|
192
|
-
// Avoids stale localTasks/localDocuments state by back-calculating
|
|
193
|
-
// world position from the actual rendered screen position of the element
|
|
194
186
|
const startPositions = new Map();
|
|
195
187
|
itemsToDrag.forEach((id) => {
|
|
196
|
-
const
|
|
197
|
-
if (
|
|
198
|
-
|
|
199
|
-
// Back-calculate world coords from actual DOM position — always accurate
|
|
200
|
-
const worldX = (rect.left - liveVpX) / liveZoom;
|
|
201
|
-
const worldY = (rect.top - liveVpY) / liveZoom;
|
|
202
|
-
startPositions.set(id, { x: worldX, y: worldY });
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
// Fallback to state if DOM element not found
|
|
206
|
-
const pos = getItemPosition(id);
|
|
207
|
-
if (pos)
|
|
208
|
-
startPositions.set(id, pos);
|
|
209
|
-
}
|
|
188
|
+
const pos = getItemPosition(id);
|
|
189
|
+
if (pos)
|
|
190
|
+
startPositions.set(id, pos);
|
|
210
191
|
});
|
|
211
192
|
const canvasObjectsStartPos = new Map();
|
|
212
193
|
selectedCanvasObjects.forEach((obj) => {
|
|
213
194
|
canvasObjectsStartPos.set(obj, { left: obj.left || 0, top: obj.top || 0 });
|
|
214
195
|
});
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const clickedPos = getItemPosition(itemId);
|
|
226
|
-
if (!clickedPos)
|
|
227
|
-
return;
|
|
228
|
-
const screenX = clickedPos.x * liveZoom + liveVpX;
|
|
229
|
-
const screenY = clickedPos.y * liveZoom + liveVpY;
|
|
230
|
-
offsetX = pointer.clientX - screenX;
|
|
231
|
-
offsetY = pointer.clientY - screenY;
|
|
232
|
-
}
|
|
196
|
+
const clickedPos = getItemPosition(itemId);
|
|
197
|
+
if (!clickedPos)
|
|
198
|
+
return;
|
|
199
|
+
// ── FIX: Read VPT directly — never stale, always frame-perfect ──
|
|
200
|
+
const vpt = fabricCanvas?.current?.viewportTransform;
|
|
201
|
+
const liveZoom = vpt ? vpt[0] : 1;
|
|
202
|
+
const liveVpX = vpt ? vpt[4] : 0;
|
|
203
|
+
const liveVpY = vpt ? vpt[5] : 0;
|
|
204
|
+
const screenX = clickedPos.x * liveZoom + liveVpX;
|
|
205
|
+
const screenY = clickedPos.y * liveZoom + liveVpY;
|
|
233
206
|
dragStateRef.current = {
|
|
234
207
|
isDragging: true,
|
|
235
208
|
itemIds: itemsToDrag,
|
|
236
209
|
startPositions,
|
|
237
210
|
canvasObjectsStartPos,
|
|
238
|
-
offsetX,
|
|
239
|
-
offsetY,
|
|
211
|
+
offsetX: pointer.clientX - screenX,
|
|
212
|
+
offsetY: pointer.clientY - screenY,
|
|
240
213
|
};
|
|
241
214
|
setDragging({ itemIds: itemsToDrag });
|
|
242
215
|
document.body.style.cursor = "grabbing";
|
|
@@ -261,13 +234,12 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
261
234
|
const firstStart = startPositions.get(firstId);
|
|
262
235
|
if (!firstStart)
|
|
263
236
|
return;
|
|
264
|
-
// ──
|
|
237
|
+
// ── FIX: Read VPT live inside rAF — perfectly in sync with Fabric ──
|
|
265
238
|
const vpt = fabricCanvas?.current?.viewportTransform;
|
|
266
239
|
const liveZoom = vpt ? vpt[0] : 1;
|
|
267
240
|
const liveVpX = vpt ? vpt[4] : 0;
|
|
268
241
|
const liveVpY = vpt ? vpt[5] : 0;
|
|
269
|
-
//
|
|
270
|
-
// subtract vpX, divide by zoom = world position
|
|
242
|
+
// Convert screen → world using live VPT values
|
|
271
243
|
const newX = (pointer.clientX - offsetX - liveVpX) / liveZoom;
|
|
272
244
|
const newY = (pointer.clientY - offsetY - liveVpY) / liveZoom;
|
|
273
245
|
const deltaX = newX - firstStart.x;
|
|
@@ -317,7 +289,7 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
317
289
|
window.removeEventListener("touchend", handleEnd);
|
|
318
290
|
window.removeEventListener("touchcancel", handleEnd);
|
|
319
291
|
};
|
|
320
|
-
}, [dragging,
|
|
292
|
+
}, [dragging, localTasks, localDocuments, fabricCanvas]);
|
|
321
293
|
// ── Selection, Status, Keyboard Logic ────────────────────────────────────────
|
|
322
294
|
const handleSelect = (id, e) => {
|
|
323
295
|
if (e?.shiftKey || e?.ctrlKey || e?.metaKey) {
|
|
@@ -369,15 +341,22 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
369
341
|
const renderItem = (id, x, y, children) => {
|
|
370
342
|
const screenX = x * canvasZoom;
|
|
371
343
|
const screenY = y * canvasZoom;
|
|
372
|
-
|
|
373
|
-
|
|
344
|
+
// 1. Detect if the user is interacting with the canvas at all
|
|
345
|
+
// 'dragging' is your existing state.
|
|
346
|
+
// You might want to pass 'isZooming' or 'isPanning' from your main canvas component here.
|
|
347
|
+
const isDragging = dragging?.itemIds.includes(id);
|
|
348
|
+
return (_jsx("div", { className: "pointer-events-auto absolute", style: {
|
|
374
349
|
left: 0,
|
|
375
350
|
top: 0,
|
|
351
|
+
// 2. Use translate3d for GPU performance
|
|
376
352
|
transform: `translate3d(${screenX}px, ${screenY}px, 0) scale(${canvasZoom})`,
|
|
377
353
|
transformOrigin: "top left",
|
|
354
|
+
// 3. THE FIX: Remove transition entirely during any viewport change
|
|
355
|
+
// Any 'ease' during zoom causes the "shaking" behavior.
|
|
378
356
|
transition: "none",
|
|
357
|
+
// 4. Optimization
|
|
379
358
|
willChange: "transform",
|
|
380
|
-
zIndex:
|
|
359
|
+
zIndex: isDragging ? 1000 : 1,
|
|
381
360
|
}, children: children }, id));
|
|
382
361
|
};
|
|
383
362
|
return (_jsx("div", { ref: overlayRef, className: "absolute inset-0 pointer-events-none", style: { zIndex: 50 }, onWheel: handleOverlayWheel, onClick: (e) => {
|