canvu-react 0.3.34 → 0.3.35

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.
package/dist/react.js CHANGED
@@ -1818,6 +1818,67 @@ function useCanvuChromeContext() {
1818
1818
  return useContext(CanvuChromeContext);
1819
1819
  }
1820
1820
 
1821
+ // src/math/item-transform.ts
1822
+ init_rect();
1823
+ function getItemRotationRad(item) {
1824
+ return item.rotation ?? 0;
1825
+ }
1826
+ function itemLocalToWorld(lx, ly, itemX, itemY, w, h, rotationRad) {
1827
+ const c = { x: w / 2, y: h / 2 };
1828
+ const dlx = lx - c.x;
1829
+ const dly = ly - c.y;
1830
+ const cos = Math.cos(rotationRad);
1831
+ const sin = Math.sin(rotationRad);
1832
+ return {
1833
+ x: itemX + c.x + cos * dlx - sin * dly,
1834
+ y: itemY + c.y + sin * dlx + cos * dly
1835
+ };
1836
+ }
1837
+ function worldToItemLocal(wx, wy, itemX, itemY, w, h, rotationRad) {
1838
+ const c = { x: w / 2, y: h / 2 };
1839
+ const vx = wx - itemX;
1840
+ const vy = wy - itemY;
1841
+ const dx = vx - c.x;
1842
+ const dy = vy - c.y;
1843
+ const cos = Math.cos(-rotationRad);
1844
+ const sin = Math.sin(-rotationRad);
1845
+ const lx = cos * dx - sin * dy;
1846
+ const ly = sin * dx + cos * dy;
1847
+ return { x: c.x + lx, y: c.y + ly };
1848
+ }
1849
+ function itemPivotWorld(item) {
1850
+ const r = normalizeRect(item.bounds);
1851
+ return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
1852
+ }
1853
+ function boundsAabbForRotatedItem(item) {
1854
+ const rot = getItemRotationRad(item);
1855
+ if (Math.abs(rot) < 1e-12 && item.bounds.width >= 0 && item.bounds.height >= 0) {
1856
+ return item.bounds;
1857
+ }
1858
+ const r = normalizeRect(item.bounds);
1859
+ if (Math.abs(rot) < 1e-12) {
1860
+ return r;
1861
+ }
1862
+ const corners = [
1863
+ [0, 0],
1864
+ [r.width, 0],
1865
+ [r.width, r.height],
1866
+ [0, r.height]
1867
+ ];
1868
+ let minX = Infinity;
1869
+ let minY = Infinity;
1870
+ let maxX = -Infinity;
1871
+ let maxY = -Infinity;
1872
+ for (const [lx, ly] of corners) {
1873
+ const p = itemLocalToWorld(lx, ly, item.x, item.y, r.width, r.height, rot);
1874
+ minX = Math.min(minX, p.x);
1875
+ minY = Math.min(minY, p.y);
1876
+ maxX = Math.max(maxX, p.x);
1877
+ maxY = Math.max(maxY, p.y);
1878
+ }
1879
+ return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
1880
+ }
1881
+
1821
1882
  // src/scene/clone-item.ts
1822
1883
  init_shape_builders();
1823
1884
  function cloneVectorSceneItemWithNewId(item) {
@@ -1857,20 +1918,25 @@ function markImageAsManaged(item) {
1857
1918
  };
1858
1919
  }
1859
1920
  function restackManagedImages(items) {
1860
- let anchor;
1921
+ let anchorAabbY = Infinity;
1922
+ let anchorCenterX = 0;
1861
1923
  for (const item of items) {
1862
1924
  if (!isManagedImage(item)) continue;
1863
- if (!anchor || item.bounds.y < anchor.bounds.y) anchor = item;
1925
+ const aabb = boundsAabbForRotatedItem(item);
1926
+ if (aabb.y < anchorAabbY) {
1927
+ anchorAabbY = aabb.y;
1928
+ anchorCenterX = aabb.x + aabb.width / 2;
1929
+ }
1864
1930
  }
1865
- if (!anchor) return [...items];
1866
- const anchorCenterX = anchor.bounds.x + anchor.bounds.width / 2;
1867
- const anchorTopY = anchor.bounds.y;
1868
- let cursorY = anchorTopY;
1931
+ if (!Number.isFinite(anchorAabbY)) return [...items];
1932
+ let cursorY = anchorAabbY;
1869
1933
  return items.map((item) => {
1870
1934
  if (!isManagedImage(item)) return item;
1935
+ const aabb = boundsAabbForRotatedItem(item);
1936
+ const centerY = cursorY + aabb.height / 2;
1871
1937
  const newX = anchorCenterX - item.bounds.width / 2;
1872
- const newY = cursorY;
1873
- cursorY = newY + item.bounds.height + STACK_GAP_WORLD;
1938
+ const newY = centerY - item.bounds.height / 2;
1939
+ cursorY += aabb.height + STACK_GAP_WORLD;
1874
1940
  if (item.bounds.x === newX && item.bounds.y === newY) return item;
1875
1941
  return {
1876
1942
  ...item,
@@ -1890,8 +1956,10 @@ function copyManagedImage(items, id) {
1890
1956
  return restackManagedImages(inserted);
1891
1957
  }
1892
1958
  function rotateManagedImage(items, id) {
1893
- return items.map(
1894
- (i) => i.id === id ? { ...i, rotation: ((i.rotation ?? 0) + Math.PI / 2) % (Math.PI * 2) } : i
1959
+ return restackManagedImages(
1960
+ items.map(
1961
+ (i) => i.id === id ? { ...i, rotation: ((i.rotation ?? 0) + Math.PI / 2) % (Math.PI * 2) } : i
1962
+ )
1895
1963
  );
1896
1964
  }
1897
1965
  function deleteManagedImage(items, id) {
@@ -2338,69 +2406,6 @@ function getBoardPositionStyle(position, inset = 12, zIndex = 40) {
2338
2406
  return base2;
2339
2407
  }
2340
2408
  }
2341
-
2342
- // src/math/item-transform.ts
2343
- init_rect();
2344
- function getItemRotationRad(item) {
2345
- return item.rotation ?? 0;
2346
- }
2347
- function itemLocalToWorld(lx, ly, itemX, itemY, w, h, rotationRad) {
2348
- const c = { x: w / 2, y: h / 2 };
2349
- const dlx = lx - c.x;
2350
- const dly = ly - c.y;
2351
- const cos = Math.cos(rotationRad);
2352
- const sin = Math.sin(rotationRad);
2353
- return {
2354
- x: itemX + c.x + cos * dlx - sin * dly,
2355
- y: itemY + c.y + sin * dlx + cos * dly
2356
- };
2357
- }
2358
- function worldToItemLocal(wx, wy, itemX, itemY, w, h, rotationRad) {
2359
- const c = { x: w / 2, y: h / 2 };
2360
- const vx = wx - itemX;
2361
- const vy = wy - itemY;
2362
- const dx = vx - c.x;
2363
- const dy = vy - c.y;
2364
- const cos = Math.cos(-rotationRad);
2365
- const sin = Math.sin(-rotationRad);
2366
- const lx = cos * dx - sin * dy;
2367
- const ly = sin * dx + cos * dy;
2368
- return { x: c.x + lx, y: c.y + ly };
2369
- }
2370
- function itemPivotWorld(item) {
2371
- const r = normalizeRect(item.bounds);
2372
- return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
2373
- }
2374
- function boundsAabbForRotatedItem(item) {
2375
- const rot = getItemRotationRad(item);
2376
- if (Math.abs(rot) < 1e-12 && item.bounds.width >= 0 && item.bounds.height >= 0) {
2377
- return item.bounds;
2378
- }
2379
- const r = normalizeRect(item.bounds);
2380
- if (Math.abs(rot) < 1e-12) {
2381
- return r;
2382
- }
2383
- const corners = [
2384
- [0, 0],
2385
- [r.width, 0],
2386
- [r.width, r.height],
2387
- [0, r.height]
2388
- ];
2389
- let minX = Infinity;
2390
- let minY = Infinity;
2391
- let maxX = -Infinity;
2392
- let maxY = -Infinity;
2393
- for (const [lx, ly] of corners) {
2394
- const p = itemLocalToWorld(lx, ly, item.x, item.y, r.width, r.height, rot);
2395
- minX = Math.min(minX, p.x);
2396
- minY = Math.min(minY, p.y);
2397
- maxX = Math.max(maxX, p.x);
2398
- maxY = Math.max(maxY, p.y);
2399
- }
2400
- return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
2401
- }
2402
-
2403
- // src/react/navmenu/minimap.tsx
2404
2409
  init_rect();
2405
2410
  var NavMenuMinimapSlotContext = createContext(null);
2406
2411
  function noop() {