@mhamz.01/easyflow-whiteboard 2.156.0 → 2.157.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":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAK9C,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;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,CAAC;CAC5D;;AAaD,wBA+tBG"}
1
+ {"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI9C,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;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,CAAC;CAC5D;;AAaD,wBA2tBG"}
@@ -3,7 +3,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React, { useState, useEffect, useRef } from "react";
4
4
  import TaskNode from "./custom-node";
5
5
  import DocumentNode from "./document-node";
6
- import { util } from "fabric";
7
6
  // ─── Component ────────────────────────────────────────────────────────────────
8
7
  export default React.memo(function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, onDocumentsUpdate, canvasZoom = 1, canvasViewport = { x: 0, y: 0 }, selectionBox = null, selectedCanvasObjects = [], fabricCanvas, canvasReady: canvasReadyProp = false, clearHtmlSelectionRef, }) {
9
8
  const [localTasks, setLocalTasks] = useState(tasks);
@@ -309,30 +308,24 @@ export default React.memo(function CanvasOverlayLayer({ tasks, documents, onTask
309
308
  if (pos)
310
309
  startPositions.set(id, pos);
311
310
  });
312
- // In handleDragStart — replace the activeSelection branch:
313
311
  const liveActiveObjects = canvas.getActiveObjects();
314
312
  const activeSelection = canvas.getActiveObject();
315
313
  const canvasObjectsStartPos = new Map();
316
- if (activeSelection && activeSelection.type === "activeSelection" && liveActiveObjects.length > 1) {
317
- // Snapshot each child's TRUE canvas-absolute position via its transform matrix,
318
- // not its group-relative left/top. This avoids drift caused by activeSelection's
319
- // internal bounding-box recalculation during the drag.
320
- liveActiveObjects.forEach((obj) => {
321
- const matrix = obj.calcTransformMatrix();
314
+ liveActiveObjects.forEach((obj) => {
315
+ if (activeSelection && activeSelection.type === "activeSelection") {
316
+ // Store group-relative left/top, NOT world transform
322
317
  canvasObjectsStartPos.set(obj, {
323
- left: matrix[4],
324
- top: matrix[5],
318
+ left: obj.left || 0,
319
+ top: obj.top || 0,
325
320
  });
326
- });
327
- }
328
- else {
329
- liveActiveObjects.forEach((obj) => {
321
+ }
322
+ else {
330
323
  canvasObjectsStartPos.set(obj, {
331
324
  left: obj.left || 0,
332
325
  top: obj.top || 0,
333
326
  });
334
- });
335
- }
327
+ }
328
+ });
336
329
  // 10. Commit to the ref for the requestAnimationFrame loop
337
330
  dragStateRef.current = {
338
331
  isDragging: true,
@@ -408,26 +401,32 @@ export default React.memo(function CanvasOverlayLayer({ tasks, documents, onTask
408
401
  y: (startPositions.get(d.id)?.y ?? d.y) + deltaY,
409
402
  }
410
403
  : d));
411
- const activeObj = canvas.getActiveObject();
412
- const isGroup = activeObj && activeObj.type === "activeSelection" && canvasObjectsStartPos.size > 1;
413
- // Precompute the group's inverse matrix ONCE per frame, not per child
414
- let groupInverseMatrix = null;
415
- if (isGroup) {
416
- const groupMatrix = activeObj.calcOwnMatrix();
417
- groupInverseMatrix = util.invertTransform(groupMatrix);
418
- }
404
+ // 7. Sync Fabric Objects (Imperative update for performance)
419
405
  canvasObjectsStartPos.forEach((startPos, obj) => {
420
- const targetAbsoluteLeft = startPos.left + deltaX;
421
- const targetAbsoluteTop = startPos.top + deltaY;
422
- if (isGroup && groupInverseMatrix) {
423
- const localPoint = util.transformPoint({ x: targetAbsoluteLeft, y: targetAbsoluteTop }, groupInverseMatrix);
424
- obj.set({ left: localPoint.x, top: localPoint.y });
425
- }
426
- else {
427
- obj.set({ left: targetAbsoluteLeft, top: targetAbsoluteTop });
428
- }
429
- obj.setCoords();
406
+ obj.set({
407
+ left: startPos.left + deltaX,
408
+ top: startPos.top + deltaY,
409
+ });
410
+ obj.setCoords(); // Required for selection/intersection accuracy
430
411
  });
412
+ const activeObj = canvas.getActiveObject();
413
+ if (activeObj && activeObj.type === "activeSelection") {
414
+ // Snapshot the group's start position once
415
+ // Move the group as a whole — Fabric will keep members' relative offsets intact
416
+ const groupStart = dragStateRef.current.canvasObjectsStartPos.get(activeObj);
417
+ if (groupStart) {
418
+ activeObj.set({ left: groupStart.left + deltaX, top: groupStart.top + deltaY });
419
+ activeObj.setCoords();
420
+ }
421
+ }
422
+ else {
423
+ // Single objects — move individually as before
424
+ canvasObjectsStartPos.forEach((startPos, obj) => {
425
+ obj.set({ left: startPos.left + deltaX, top: startPos.top + deltaY });
426
+ obj.setCoords();
427
+ });
428
+ }
429
+ // 8. Single render call for all Fabric changes
431
430
  canvas.requestRenderAll();
432
431
  });
433
432
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhamz.01/easyflow-whiteboard",
3
- "version": "2.156.0",
3
+ "version": "2.157.0",
4
4
  "description": "A feature-rich whiteboard component built with Fabric.js and React",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",