@mhamz.01/easyflow-whiteboard 2.81.0 → 2.82.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-fix.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-fix.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAkB,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAQhF,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,2CA0SzB"}
1
+ {"version":3,"file":"custom-node-overlay-fix.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-fix.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAkB,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAQhF,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,2CAiTzB"}
@@ -11,8 +11,6 @@ import { useCanvasReady } from "./hooks/useCanvasReady";
11
11
  import { useNodeSync } from "./hooks/useNodeSync";
12
12
  export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, onDocumentsUpdate, canvasZoom = 1, canvasViewport = { x: 0, y: 0 }, selectionBox = null, selectedCanvasObjects = [], fabricCanvas, }) {
13
13
  // ─── State Management ──────────────────────────────────────────────────
14
- const [liveViewport, setLiveViewport] = useState(canvasViewport);
15
- const [liveZoom, setLiveZoom] = useState(canvasZoom);
16
14
  const [localTasks, setLocalTasks] = useState(tasks);
17
15
  const [localDocuments, setLocalDocuments] = useState(documents);
18
16
  const [selectedIds, setSelectedIds] = useState(new Set());
@@ -26,10 +24,6 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
26
24
  fabricCanvas,
27
25
  canvasZoom,
28
26
  canvasReady,
29
- onViewportChange: useCallback((viewport, zoom) => {
30
- setLiveViewport(viewport);
31
- setLiveZoom(zoom);
32
- }, []),
33
27
  });
34
28
  const { dragStateRef: dragRef, rafIdRef, getPointerEvent, getViewportTransform, handleDragStart: handleDragStartHook, handleDragMove: handleDragMoveHook, handleDragEnd: handleDragEndHook, } = useNodeDrag({
35
29
  selectedIds,
@@ -173,6 +167,14 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
173
167
  onTasksUpdate?.(updated);
174
168
  }, [localTasks, onTasksUpdate]);
175
169
  // ─── Render Helper ────────────────────────────────────────────────────
170
+ const getCanvasViewport = () => {
171
+ const canvas = fabricCanvas?.current;
172
+ if (!canvas)
173
+ return { x: 0, y: 0 };
174
+ const vpt = canvas.viewportTransform;
175
+ return vpt ? { x: vpt[4], y: vpt[5] } : { x: 0, y: 0 };
176
+ };
177
+ const currentViewport = getCanvasViewport(); // ← Get FRESH viewport every render
176
178
  const renderItem = useCallback((id, x, y, children) => {
177
179
  const screenX = x * canvasZoom;
178
180
  const screenY = y * canvasZoom;
@@ -192,7 +194,7 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
192
194
  if (e.target === e.currentTarget)
193
195
  setSelectedIds(new Set());
194
196
  }, children: _jsxs("div", { className: "absolute top-0 left-0 pointer-events-none", style: {
195
- transform: `translate(${canvasViewport.x}px, ${canvasViewport.y}px)`,
197
+ transform: `translate(${currentViewport.x}px, ${currentViewport.y}px)`, // ← Use fresh viewport
196
198
  transformOrigin: "top left",
197
199
  }, 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 })))] }) }));
198
200
  }
@@ -78,7 +78,7 @@ export function useNodeDrag({ selectedIds, fabricCanvas, selectedCanvasObjects,
78
78
  if (rafIdRef.current !== null)
79
79
  cancelAnimationFrame(rafIdRef.current);
80
80
  rafIdRef.current = requestAnimationFrame(() => {
81
- const { itemIds, startPositions, canvasObjectsStartPos, offsetX, offsetY } = dragStateRef.current;
81
+ const { canvasObjectsStartPos, offsetX, offsetY } = dragStateRef.current;
82
82
  const canvas = fabricCanvas?.current;
83
83
  if (!canvas)
84
84
  return;
@@ -4,12 +4,8 @@ interface UseWheelZoomProps {
4
4
  fabricCanvas?: React.RefObject<Canvas | null>;
5
5
  canvasZoom?: number;
6
6
  canvasReady?: boolean;
7
- onViewportChange: (viewport: {
8
- x: number;
9
- y: number;
10
- }, zoom: number) => void;
11
7
  }
12
- export declare function useWheelZoom({ overlayRef, fabricCanvas, canvasZoom, canvasReady, onViewportChange, }: UseWheelZoomProps): {
8
+ export declare function useWheelZoom({ overlayRef, fabricCanvas, canvasZoom, canvasReady, }: UseWheelZoomProps): {
13
9
  handleOverlayWheel: (e: React.WheelEvent) => void;
14
10
  };
15
11
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useWheelZoom.d.ts","sourceRoot":"","sources":["../../../../src/components/node/hooks/useWheelZoom.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,UAAU,iBAAiB;IACvB,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,CAAC,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9E;AAED,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,YAAY,EACZ,UAAc,EACd,WAAmB,EACnB,gBAAgB,GACjB,EAAE,iBAAiB;4BAEa,KAAK,CAAC,UAAU;EAqFhD"}
1
+ {"version":3,"file":"useWheelZoom.d.ts","sourceRoot":"","sources":["../../../../src/components/node/hooks/useWheelZoom.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,UAAU,iBAAiB;IACvB,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,YAAY,EACZ,UAAc,EACd,WAAmB,GACpB,EAAE,iBAAiB;4BAEa,KAAK,CAAC,UAAU;EA6DhD"}
@@ -1,5 +1,5 @@
1
1
  import { useEffect } from "react";
2
- export function useWheelZoom({ overlayRef, fabricCanvas, canvasZoom = 1, canvasReady = false, onViewportChange, }) {
2
+ export function useWheelZoom({ overlayRef, fabricCanvas, canvasZoom = 1, canvasReady = false, }) {
3
3
  // React event handler for overlay wheel
4
4
  const handleOverlayWheel = (e) => {
5
5
  if (e.ctrlKey || e.metaKey || e.shiftKey) {
@@ -22,26 +22,6 @@ export function useWheelZoom({ overlayRef, fabricCanvas, canvasZoom = 1, canvasR
22
22
  e.stopPropagation();
23
23
  }
24
24
  };
25
- useEffect(() => {
26
- const canvas = fabricCanvas?.current;
27
- if (!canvas || !canvasReady)
28
- return;
29
- // THE FIX: Listen to Fabric's internal render loop
30
- // This fires immediately after Fabric moves, reducing the lag time
31
- const syncViewport = () => {
32
- const vpt = canvas.viewportTransform;
33
- if (vpt) {
34
- onViewportChange({ x: vpt[4], y: vpt[5] }, // Pan position
35
- canvas.getZoom() // Zoom level
36
- );
37
- }
38
- };
39
- // Use 'after:render' for the tightest possible sync
40
- canvas.on("after:render", syncViewport);
41
- return () => {
42
- canvas.off("after:render", syncViewport);
43
- };
44
- }, [fabricCanvas, canvasReady, onViewportChange]);
45
25
  // Global wheel event for hovering over nodes
46
26
  useEffect(() => {
47
27
  const overlayEl = overlayRef.current;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhamz.01/easyflow-whiteboard",
3
- "version": "2.81.0",
3
+ "version": "2.82.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",