@mhamz.01/easyflow-whiteboard 2.66.0 → 2.67.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;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,2CAkkBzB"}
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,2CAujBzB"}
@@ -220,16 +220,12 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
220
220
  return e;
221
221
  };
222
222
  const handleDragStart = (itemId, e) => {
223
- // 1. Safety check for the Fabric instance
224
223
  const canvas = fabricCanvas?.current;
225
224
  if (!canvas)
226
225
  return;
227
- // 2. Normalize the event (Touch vs Mouse)
228
226
  if (e.cancelable)
229
227
  e.preventDefault();
230
228
  const pointer = getPointerEvent(e);
231
- // 3. Determine which items are being dragged
232
- // selection update DOES NOT trigger before drag snapshot
233
229
  let itemsToDrag;
234
230
  if (selectedIds.has(itemId)) {
235
231
  itemsToDrag = Array.from(selectedIds);
@@ -238,53 +234,39 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
238
234
  itemsToDrag = [itemId];
239
235
  setSelectedIds(new Set([itemId]));
240
236
  }
241
- // 4. Capture current World Transform (Zoom & Pan)
242
- // We read directly from the canvas to ensure zero-frame lag
243
237
  const vpt = canvas.viewportTransform || [1, 0, 0, 1, 0, 0];
244
238
  const liveZoom = vpt[0];
245
239
  const liveVpX = vpt[4];
246
240
  const liveVpY = vpt[5];
247
- // 5. Convert the Click Position from Screen Pixels to World Units
248
241
  const clickWorldX = (pointer.clientX - liveVpX) / liveZoom;
249
242
  const clickWorldY = (pointer.clientY - liveVpY) / liveZoom;
250
- // 6. Get the clicked item's current World Position
251
243
  const clickedPos = getItemPosition(itemId);
252
244
  if (!clickedPos)
253
245
  return;
254
- // 7. Calculate the Offset in WORLD UNITS
255
- // This is the distance from the mouse to the node's top-left in the infinite grid.
256
- // This value remains constant even if you zoom during the drag.
257
246
  const worldOffsetX = clickWorldX - clickedPos.x;
258
247
  const worldOffsetY = clickWorldY - clickedPos.y;
259
- // 8. Snapshot starting positions for all selected HTML nodes
260
248
  const startPositions = new Map();
261
249
  itemsToDrag.forEach((id) => {
262
250
  const pos = getItemPosition(id);
263
251
  if (pos)
264
252
  startPositions.set(id, pos);
265
253
  });
266
- // 9. Snapshot starting positions for all selected Fabric objects
267
254
  const canvasObjectsStartPos = new Map();
268
255
  selectedCanvasObjects.forEach((obj) => {
269
256
  canvasObjectsStartPos.set(obj, { left: obj.left || 0, top: obj.top || 0 });
270
257
  });
271
- // 10. Commit to the ref for the requestAnimationFrame loop
272
258
  dragStateRef.current = {
273
259
  isDragging: true,
274
260
  itemIds: itemsToDrag,
275
261
  startPositions,
276
262
  canvasObjectsStartPos,
277
- offsetX: worldOffsetX, // Now stored as World Units
278
- offsetY: worldOffsetY, // Now stored as World Units
263
+ offsetX: worldOffsetX,
264
+ offsetY: worldOffsetY,
279
265
  };
280
- if (!selectedIds.has(itemId) && dragStateRef.current.itemIds.length === 0) {
281
- setSelectedIds(new Set([itemId]));
282
- }
283
- // 11. Trigger UI states
284
266
  setDragging({ itemIds: itemsToDrag });
267
+ // ── ATTACH LISTENERS DIRECTLY ──
285
268
  document.body.style.cursor = "grabbing";
286
269
  document.body.style.userSelect = "none";
287
- document.body.style.touchAction = "none";
288
270
  };
289
271
  // ── Drag move (HTML Node side) ───────────────────────────────────────────────
290
272
  useEffect(() => {
@@ -349,13 +331,18 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
349
331
  });
350
332
  };
351
333
  const handleEnd = () => {
352
- dragStateRef.current.isDragging = false;
353
334
  if (rafIdRef.current !== null)
354
335
  cancelAnimationFrame(rafIdRef.current);
336
+ // 1. Kill the flag first
337
+ dragStateRef.current.isDragging = false;
355
338
  setDragging(null);
339
+ // 2. Remove the listeners immediately
340
+ window.removeEventListener("mousemove", handleMove);
341
+ window.removeEventListener("mouseup", handleEnd);
342
+ window.removeEventListener("touchmove", handleMove);
343
+ window.removeEventListener("touchend", handleEnd);
356
344
  document.body.style.cursor = "";
357
345
  document.body.style.userSelect = "";
358
- document.body.style.touchAction = "";
359
346
  onTasksUpdate?.(localTasks);
360
347
  onDocumentsUpdate?.(localDocuments);
361
348
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhamz.01/easyflow-whiteboard",
3
- "version": "2.66.0",
3
+ "version": "2.67.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",