canvu-react 0.3.23 → 0.3.24
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/index.cjs +18 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +18 -9
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +72 -46
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +72 -46
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -1611,6 +1611,21 @@ function reorderManagedImages(items, orderedManagedIds) {
|
|
|
1611
1611
|
});
|
|
1612
1612
|
return restackManagedImages(next);
|
|
1613
1613
|
}
|
|
1614
|
+
var OPEN_KEYFRAME_ID = "canvu-images-menu-open-keyframe";
|
|
1615
|
+
var OPEN_KEYFRAME_CSS = `
|
|
1616
|
+
@keyframes canvu-images-menu-open {
|
|
1617
|
+
from { opacity: 0; transform: scale(0.6); }
|
|
1618
|
+
to { opacity: 1; transform: scale(1); }
|
|
1619
|
+
}
|
|
1620
|
+
`;
|
|
1621
|
+
function ensureOpenKeyframe() {
|
|
1622
|
+
if (typeof document === "undefined") return;
|
|
1623
|
+
if (document.getElementById(OPEN_KEYFRAME_ID)) return;
|
|
1624
|
+
const style = document.createElement("style");
|
|
1625
|
+
style.id = OPEN_KEYFRAME_ID;
|
|
1626
|
+
style.textContent = OPEN_KEYFRAME_CSS;
|
|
1627
|
+
document.head.appendChild(style);
|
|
1628
|
+
}
|
|
1614
1629
|
var panelStyle = {
|
|
1615
1630
|
width: "fit-content",
|
|
1616
1631
|
maxHeight: "min(85dvh, 820px)",
|
|
@@ -1621,7 +1636,9 @@ var panelStyle = {
|
|
|
1621
1636
|
boxShadow: "0 10px 40px rgba(15, 23, 42, 0.12)",
|
|
1622
1637
|
fontFamily: "system-ui, sans-serif",
|
|
1623
1638
|
fontSize: 14,
|
|
1624
|
-
color: "#0f172a"
|
|
1639
|
+
color: "#0f172a",
|
|
1640
|
+
transformOrigin: "top right",
|
|
1641
|
+
animation: "canvu-images-menu-open 180ms cubic-bezier(0.2, 0.8, 0.2, 1)"
|
|
1625
1642
|
};
|
|
1626
1643
|
var headerStyle = {
|
|
1627
1644
|
display: "flex",
|
|
@@ -1743,33 +1760,16 @@ var collapsedButtonStyle = {
|
|
|
1743
1760
|
display: "inline-flex",
|
|
1744
1761
|
alignItems: "center",
|
|
1745
1762
|
justifyContent: "center",
|
|
1746
|
-
|
|
1763
|
+
width: 44,
|
|
1747
1764
|
height: 44,
|
|
1748
|
-
|
|
1749
|
-
padding: "0 12px",
|
|
1765
|
+
padding: 0,
|
|
1750
1766
|
border: "1px solid #e2e8f0",
|
|
1751
|
-
borderRadius:
|
|
1767
|
+
borderRadius: 10,
|
|
1752
1768
|
background: "#ffffff",
|
|
1753
1769
|
color: "#0f172a",
|
|
1754
1770
|
cursor: "pointer",
|
|
1755
|
-
fontFamily: "system-ui, sans-serif",
|
|
1756
|
-
fontSize: 13,
|
|
1757
|
-
fontWeight: 600,
|
|
1758
1771
|
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.12)"
|
|
1759
1772
|
};
|
|
1760
|
-
var collapsedCountStyle = {
|
|
1761
|
-
display: "inline-flex",
|
|
1762
|
-
alignItems: "center",
|
|
1763
|
-
justifyContent: "center",
|
|
1764
|
-
minWidth: 20,
|
|
1765
|
-
height: 20,
|
|
1766
|
-
padding: "0 6px",
|
|
1767
|
-
borderRadius: 10,
|
|
1768
|
-
backgroundColor: "#0f172a",
|
|
1769
|
-
color: "#ffffff",
|
|
1770
|
-
fontSize: 11,
|
|
1771
|
-
fontWeight: 600
|
|
1772
|
-
};
|
|
1773
1773
|
var defaultLabels = {
|
|
1774
1774
|
title: "Images",
|
|
1775
1775
|
dragHandle: "Drag to reorder",
|
|
@@ -1793,12 +1793,15 @@ function ImagesMenu({
|
|
|
1793
1793
|
})
|
|
1794
1794
|
);
|
|
1795
1795
|
const [collapsed, setCollapsed] = react.useState(false);
|
|
1796
|
+
react.useEffect(() => {
|
|
1797
|
+
ensureOpenKeyframe();
|
|
1798
|
+
}, []);
|
|
1796
1799
|
if (managed.length === 0) {
|
|
1797
1800
|
return null;
|
|
1798
1801
|
}
|
|
1799
1802
|
const resolvedLabels = { ...defaultLabels, ...labels };
|
|
1800
1803
|
if (collapsed) {
|
|
1801
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
1804
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1802
1805
|
"button",
|
|
1803
1806
|
{
|
|
1804
1807
|
type: "button",
|
|
@@ -1807,10 +1810,7 @@ function ImagesMenu({
|
|
|
1807
1810
|
"aria-label": resolvedLabels.expand,
|
|
1808
1811
|
title: resolvedLabels.expand,
|
|
1809
1812
|
onClick: () => setCollapsed(false),
|
|
1810
|
-
children:
|
|
1811
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Images, { size: 20 }),
|
|
1812
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: collapsedCountStyle, children: managed.length })
|
|
1813
|
-
]
|
|
1813
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Images, { size: 20 })
|
|
1814
1814
|
}
|
|
1815
1815
|
);
|
|
1816
1816
|
}
|
|
@@ -1879,11 +1879,20 @@ function ImagesMenuRow({
|
|
|
1879
1879
|
onRotate,
|
|
1880
1880
|
onDelete
|
|
1881
1881
|
}) {
|
|
1882
|
-
const {
|
|
1882
|
+
const {
|
|
1883
|
+
attributes,
|
|
1884
|
+
listeners,
|
|
1885
|
+
setNodeRef,
|
|
1886
|
+
setActivatorNodeRef,
|
|
1887
|
+
transform,
|
|
1888
|
+
transition,
|
|
1889
|
+
isDragging
|
|
1890
|
+
} = sortable.useSortable({ id: item.id });
|
|
1891
|
+
const feedbackTransition = "background-color 140ms ease, opacity 140ms ease";
|
|
1883
1892
|
const wrapperStyle = {
|
|
1884
1893
|
...rowStyle,
|
|
1885
1894
|
transform: utilities.CSS.Transform.toString(transform),
|
|
1886
|
-
transition,
|
|
1895
|
+
transition: transition ? `${transition}, ${feedbackTransition}` : feedbackTransition,
|
|
1887
1896
|
background: isDragging ? "#eef2f7" : "transparent",
|
|
1888
1897
|
opacity: isDragging ? 0.85 : 1
|
|
1889
1898
|
};
|
|
@@ -1892,6 +1901,7 @@ function ImagesMenuRow({
|
|
|
1892
1901
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1893
1902
|
"button",
|
|
1894
1903
|
{
|
|
1904
|
+
ref: setActivatorNodeRef,
|
|
1895
1905
|
type: "button",
|
|
1896
1906
|
style: handleStyle,
|
|
1897
1907
|
"aria-label": labels.dragHandle,
|
|
@@ -4786,16 +4796,23 @@ function distanceBetween(a, b) {
|
|
|
4786
4796
|
function midpoint(a, b) {
|
|
4787
4797
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
4788
4798
|
}
|
|
4789
|
-
function
|
|
4790
|
-
switch (
|
|
4799
|
+
function wheelDeltaPixels(delta, deltaMode) {
|
|
4800
|
+
switch (deltaMode) {
|
|
4791
4801
|
case WheelEvent.DOM_DELTA_LINE:
|
|
4792
|
-
return
|
|
4802
|
+
return delta * 16;
|
|
4793
4803
|
case WheelEvent.DOM_DELTA_PAGE:
|
|
4794
|
-
return
|
|
4804
|
+
return delta * 400;
|
|
4795
4805
|
default:
|
|
4796
|
-
return
|
|
4806
|
+
return delta;
|
|
4797
4807
|
}
|
|
4798
4808
|
}
|
|
4809
|
+
var TRACKPAD_MAX_DELTA = 20;
|
|
4810
|
+
var MOUSE_WHEEL_DAMPING = 0.4;
|
|
4811
|
+
function softenWheelDelta(d) {
|
|
4812
|
+
const a = Math.abs(d);
|
|
4813
|
+
if (a <= TRACKPAD_MAX_DELTA) return d;
|
|
4814
|
+
return Math.sign(d) * (TRACKPAD_MAX_DELTA + (a - TRACKPAD_MAX_DELTA) * MOUSE_WHEEL_DAMPING);
|
|
4815
|
+
}
|
|
4799
4816
|
function attachViewportInput(options) {
|
|
4800
4817
|
const {
|
|
4801
4818
|
element,
|
|
@@ -4818,8 +4835,8 @@ function attachViewportInput(options) {
|
|
|
4818
4835
|
const onWheel = (e) => {
|
|
4819
4836
|
if (e.ctrlKey || e.metaKey) {
|
|
4820
4837
|
e.preventDefault();
|
|
4821
|
-
const dy =
|
|
4822
|
-
const normDy = Math.abs(dy) <
|
|
4838
|
+
const dy = wheelDeltaPixels(e.deltaY, e.deltaMode);
|
|
4839
|
+
const normDy = Math.abs(dy) < TRACKPAD_MAX_DELTA ? dy * 12 : dy;
|
|
4823
4840
|
const factor = Math.exp(-normDy * wheelZoomSensitivity);
|
|
4824
4841
|
const rect = element.getBoundingClientRect();
|
|
4825
4842
|
camera.setZoom(camera.zoom * factor, {
|
|
@@ -4830,8 +4847,10 @@ function attachViewportInput(options) {
|
|
|
4830
4847
|
return;
|
|
4831
4848
|
}
|
|
4832
4849
|
e.preventDefault();
|
|
4833
|
-
|
|
4834
|
-
|
|
4850
|
+
const panDx = softenWheelDelta(wheelDeltaPixels(e.deltaX, e.deltaMode));
|
|
4851
|
+
const panDy = softenWheelDelta(wheelDeltaPixels(e.deltaY, e.deltaMode));
|
|
4852
|
+
camera.x -= panDx * wheelPanSensitivity / camera.zoom;
|
|
4853
|
+
camera.y -= panDy * wheelPanSensitivity / camera.zoom;
|
|
4835
4854
|
onUpdate();
|
|
4836
4855
|
};
|
|
4837
4856
|
const onPointerDown = (e) => {
|
|
@@ -7658,15 +7677,22 @@ var VectorViewport = react.forwardRef(
|
|
|
7658
7677
|
react.useEffect(() => {
|
|
7659
7678
|
rememberImageBlobHrefs(items, rememberedImageBlobHrefsRef.current);
|
|
7660
7679
|
}, [items]);
|
|
7661
|
-
react.
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7680
|
+
const blobRevokeTimerRef = react.useRef(null);
|
|
7681
|
+
react.useEffect(() => {
|
|
7682
|
+
if (blobRevokeTimerRef.current !== null) {
|
|
7683
|
+
clearTimeout(blobRevokeTimerRef.current);
|
|
7684
|
+
blobRevokeTimerRef.current = null;
|
|
7685
|
+
}
|
|
7686
|
+
return () => {
|
|
7687
|
+
blobRevokeTimerRef.current = setTimeout(() => {
|
|
7688
|
+
releaseRememberedBlobHrefs(
|
|
7689
|
+
rememberedImageBlobHrefsRef.current,
|
|
7690
|
+
(href) => URL.revokeObjectURL(href)
|
|
7691
|
+
);
|
|
7692
|
+
blobRevokeTimerRef.current = null;
|
|
7693
|
+
}, 100);
|
|
7694
|
+
};
|
|
7695
|
+
}, []);
|
|
7670
7696
|
const PASTE_OFFSET_WORLD = 24;
|
|
7671
7697
|
const copyIdsToInternalClipboard = react.useCallback((ids) => {
|
|
7672
7698
|
if (ids.length === 0) return;
|