@mhamz.01/easyflow-whiteboard 2.88.0 → 2.89.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;AAO9C,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;CACvB;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,2CAomBzB"}
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;AAS9C,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;CACvB;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,2CAglBzB"}
@@ -5,12 +5,15 @@ import TaskNode from "./custom-node";
5
5
  import DocumentNode from "./document-node";
6
6
  // ─── Component ────────────────────────────────────────────────────────────────
7
7
  export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, onDocumentsUpdate, canvasZoom = 1, canvasViewport = { x: 0, y: 0 }, selectionBox = null, selectedCanvasObjects = [], fabricCanvas, }) {
8
- const [liveVpt, setLiveVpt] = useState({ x: canvasViewport.x, y: canvasViewport.y, zoom: canvasZoom });
9
8
  const [localTasks, setLocalTasks] = useState(tasks);
10
9
  const [localDocuments, setLocalDocuments] = useState(documents);
11
10
  const [selectedIds, setSelectedIds] = useState(new Set());
12
11
  const [dragging, setDragging] = useState(null);
13
12
  const [canvasReady, setCanvasReady] = useState(false);
13
+ const nodeClipboardRef = useRef({
14
+ tasks: [],
15
+ documents: [],
16
+ });
14
17
  const dragStateRef = useRef({
15
18
  isDragging: false,
16
19
  itemIds: [],
@@ -163,20 +166,6 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
163
166
  // change, creating a new closure each time. The second drag captured a stale
164
167
  // or empty selectedIds from the closure at re-registration time.
165
168
  }, [canvasZoom, fabricCanvas, canvasReady]);
166
- // 2. Sync directly with Fabric's render heartbeat
167
- useEffect(() => {
168
- const canvas = fabricCanvas?.current;
169
- if (!canvas)
170
- return;
171
- const sync = () => {
172
- const vpt = canvas.viewportTransform;
173
- if (vpt) {
174
- setLiveVpt({ x: vpt[4], y: vpt[5], zoom: vpt[0] });
175
- }
176
- };
177
- canvas.on("after:render", sync);
178
- return () => { canvas.off("after:render", sync); };
179
- }, [fabricCanvas, canvasReady]);
180
169
  // ── Helpers ─────────────────────────────────────────────────────────────────
181
170
  const getItemPosition = (id) => {
182
171
  const task = localTasks.find((t) => t.id === id);
@@ -439,17 +428,17 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
439
428
  }, [localTasks, localDocuments, selectedIds, onTasksUpdate, onDocumentsUpdate]);
440
429
  // ── Render helper ────────────────────────────────────────────────────────────
441
430
  const renderItem = (id, x, y, children) => {
442
- const screenX = x * liveVpt.zoom;
443
- const screenY = y * liveVpt.zoom;
444
- const isDragging = dragging?.itemIds.includes(id);
431
+ const screenX = x * canvasZoom;
432
+ const screenY = y * canvasZoom;
445
433
  // 1. Detect if the user is interacting with the canvas at all
446
434
  // 'dragging' is your existing state.
447
435
  // You might want to pass 'isZooming' or 'isPanning' from your main canvas component here.
436
+ const isDragging = dragging?.itemIds.includes(id);
448
437
  return (_jsx("div", { className: "pointer-events-auto absolute", style: {
449
438
  left: 0,
450
439
  top: 0,
451
440
  // 2. Use translate3d for GPU performance
452
- transform: `translate3d(${screenX}px, ${screenY}px, 0) scale(${liveVpt.zoom})`,
441
+ transform: `translate3d(${screenX}px, ${screenY}px, 0) scale(${canvasZoom})`,
453
442
  transformOrigin: "top left",
454
443
  // 3. THE FIX: Remove transition entirely during any viewport change
455
444
  // Any 'ease' during zoom causes the "shaking" behavior.
@@ -463,8 +452,7 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
463
452
  if (e.target === e.currentTarget)
464
453
  setSelectedIds(new Set());
465
454
  }, children: _jsxs("div", { className: "absolute top-0 left-0 pointer-events-none", style: {
466
- transform: `translate3d(${liveVpt.x}px, ${liveVpt.y}px, 0)`,
455
+ transform: `translate(${canvasViewport.x}px, ${canvasViewport.y}px)`,
467
456
  transformOrigin: "top left",
468
- willChange: "transform",
469
457
  }, children: [localTasks.map((task) => renderItem(task.id, task.x, task.y, _jsx(TaskNode, { ...task, isSelected: selectedIds.has(task.id), onSelect: handleSelect, onDragStart: handleDragStart, onStatusChange: handleStatusChange, zoom: 1 }))), localDocuments.map((doc) => renderItem(doc.id, doc.x, doc.y, _jsx(DocumentNode, { ...doc, isSelected: selectedIds.has(doc.id), onSelect: handleSelect, onDragStart: handleDragStart })))] }) }));
470
458
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhamz.01/easyflow-whiteboard",
3
- "version": "2.88.0",
3
+ "version": "2.89.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",