@pixerate/editor-react 0.20.0 → 0.22.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.
- package/dist/canvas/index.cjs +749 -505
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +57 -4
- package/dist/canvas/index.d.ts +57 -4
- package/dist/canvas/index.js +410 -162
- package/dist/canvas/index.js.map +1 -1
- package/package.json +5 -4
package/dist/canvas/index.js
CHANGED
|
@@ -976,8 +976,220 @@ function CanvasGuidesLayer({
|
|
|
976
976
|
);
|
|
977
977
|
}
|
|
978
978
|
|
|
979
|
+
// src/canvas/useCanvasDraw.ts
|
|
980
|
+
import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef7, useState as useState3 } from "react";
|
|
981
|
+
import {
|
|
982
|
+
createCanvasDrawController
|
|
983
|
+
} from "@pixerate/editor/canvas";
|
|
984
|
+
function useCanvasDraw(options) {
|
|
985
|
+
const nodesRef = useRef7(options.nodes);
|
|
986
|
+
nodesRef.current = options.nodes;
|
|
987
|
+
const optionsRef = useRef7(options);
|
|
988
|
+
optionsRef.current = options;
|
|
989
|
+
const [tool, setToolState] = useState3(options.initialTool ?? "select");
|
|
990
|
+
const [activeStroke, setActiveStroke] = useState3(null);
|
|
991
|
+
const controller = useMemo3(
|
|
992
|
+
() => createCanvasDrawController({
|
|
993
|
+
getNodes: () => nodesRef.current,
|
|
994
|
+
setNodes: (next) => {
|
|
995
|
+
nodesRef.current = next;
|
|
996
|
+
optionsRef.current.setNodes(next);
|
|
997
|
+
},
|
|
998
|
+
get history() {
|
|
999
|
+
return optionsRef.current.history;
|
|
1000
|
+
},
|
|
1001
|
+
tool: options.initialTool ?? "select",
|
|
1002
|
+
style: options.initialStyle,
|
|
1003
|
+
drawOptions: options.drawOptions,
|
|
1004
|
+
generateNodeId: options.generateNodeId,
|
|
1005
|
+
onToolChange: setToolState,
|
|
1006
|
+
onStyleChange: (s) => setStyleState(s),
|
|
1007
|
+
onActiveStrokeChange: setActiveStroke,
|
|
1008
|
+
onStrokeComplete: (n) => optionsRef.current.onStrokeComplete?.(n),
|
|
1009
|
+
onNodesErase: (erased) => optionsRef.current.onNodesErase?.(erased)
|
|
1010
|
+
}),
|
|
1011
|
+
[]
|
|
1012
|
+
);
|
|
1013
|
+
const [style, setStyleState] = useState3(controller.style);
|
|
1014
|
+
useEffect4(() => {
|
|
1015
|
+
if (options.initialTool && options.initialTool !== controller.tool) {
|
|
1016
|
+
controller.setTool(options.initialTool);
|
|
1017
|
+
}
|
|
1018
|
+
}, [options.initialTool, controller]);
|
|
1019
|
+
return useMemo3(
|
|
1020
|
+
() => ({
|
|
1021
|
+
tool,
|
|
1022
|
+
style,
|
|
1023
|
+
activeStroke,
|
|
1024
|
+
isDrawing: activeStroke !== null,
|
|
1025
|
+
setTool: controller.setTool,
|
|
1026
|
+
setStyle: controller.setStyle,
|
|
1027
|
+
startStroke: controller.startStroke,
|
|
1028
|
+
continueStroke: controller.continueStroke,
|
|
1029
|
+
endStroke: controller.endStroke,
|
|
1030
|
+
cancelStroke: controller.cancelStroke,
|
|
1031
|
+
eraseAt: controller.eraseAt
|
|
1032
|
+
}),
|
|
1033
|
+
[tool, style, activeStroke, controller]
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// src/canvas/CanvasDrawLayer.tsx
|
|
1038
|
+
import { useCallback as useCallback7, useEffect as useEffect5, useRef as useRef8, useState as useState4 } from "react";
|
|
1039
|
+
import {
|
|
1040
|
+
strokePointsToPathData,
|
|
1041
|
+
resolveCanvasGradient,
|
|
1042
|
+
gradientToSvgDef
|
|
1043
|
+
} from "@pixerate/editor/canvas";
|
|
1044
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1045
|
+
var DEFAULT_VIEWPORT2 = { x: 0, y: 0, zoom: 1 };
|
|
1046
|
+
function CanvasDrawLayer({
|
|
1047
|
+
draw,
|
|
1048
|
+
viewport = DEFAULT_VIEWPORT2,
|
|
1049
|
+
className = "",
|
|
1050
|
+
style,
|
|
1051
|
+
cursor,
|
|
1052
|
+
eraserRadius = 12
|
|
1053
|
+
}) {
|
|
1054
|
+
const svgRef = useRef8(null);
|
|
1055
|
+
const [spaceHeld, setSpaceHeld] = useState4(false);
|
|
1056
|
+
const [eraserPos, setEraserPos] = useState4(null);
|
|
1057
|
+
useEffect5(() => {
|
|
1058
|
+
function onKeyDown(e) {
|
|
1059
|
+
if (e.code === "Space" && !e.repeat) {
|
|
1060
|
+
const tag = e.target?.tagName;
|
|
1061
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || e.target?.isContentEditable) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
setSpaceHeld(true);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
function onKeyUp(e) {
|
|
1068
|
+
if (e.code === "Space") {
|
|
1069
|
+
setSpaceHeld(false);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
window.addEventListener("keydown", onKeyDown);
|
|
1073
|
+
window.addEventListener("keyup", onKeyUp);
|
|
1074
|
+
return () => {
|
|
1075
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
1076
|
+
window.removeEventListener("keyup", onKeyUp);
|
|
1077
|
+
};
|
|
1078
|
+
}, []);
|
|
1079
|
+
const clientToFlow = useCallback7(
|
|
1080
|
+
(clientX, clientY) => {
|
|
1081
|
+
if (!svgRef.current) return [0, 0];
|
|
1082
|
+
const rect = svgRef.current.getBoundingClientRect();
|
|
1083
|
+
const screenX = clientX - rect.left;
|
|
1084
|
+
const screenY = clientY - rect.top;
|
|
1085
|
+
const flowX = (screenX - viewport.x) / viewport.zoom;
|
|
1086
|
+
const flowY = (screenY - viewport.y) / viewport.zoom;
|
|
1087
|
+
return [flowX, flowY];
|
|
1088
|
+
},
|
|
1089
|
+
[viewport.x, viewport.y, viewport.zoom]
|
|
1090
|
+
);
|
|
1091
|
+
const isDrawingMode = draw.tool !== "select";
|
|
1092
|
+
const interactive = isDrawingMode && !spaceHeld;
|
|
1093
|
+
const handlePointerDown = (e) => {
|
|
1094
|
+
if (!interactive || e.button !== 0) return;
|
|
1095
|
+
e.preventDefault();
|
|
1096
|
+
e.stopPropagation();
|
|
1097
|
+
e.target.setPointerCapture?.(e.pointerId);
|
|
1098
|
+
const flowPt = clientToFlow(e.clientX, e.clientY);
|
|
1099
|
+
draw.startStroke(flowPt);
|
|
1100
|
+
if (draw.tool === "eraser") {
|
|
1101
|
+
setEraserPos([e.clientX, e.clientY]);
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
const handlePointerMove = (e) => {
|
|
1105
|
+
if (draw.tool === "eraser" && !spaceHeld) {
|
|
1106
|
+
setEraserPos([e.clientX, e.clientY]);
|
|
1107
|
+
}
|
|
1108
|
+
if (!interactive) return;
|
|
1109
|
+
if (e.buttons === 1) {
|
|
1110
|
+
e.preventDefault();
|
|
1111
|
+
e.stopPropagation();
|
|
1112
|
+
const flowPt = clientToFlow(e.clientX, e.clientY);
|
|
1113
|
+
draw.continueStroke(flowPt);
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
const handlePointerUp = (e) => {
|
|
1117
|
+
if (!interactive || e.button !== 0) return;
|
|
1118
|
+
e.preventDefault();
|
|
1119
|
+
e.stopPropagation();
|
|
1120
|
+
try {
|
|
1121
|
+
e.target.releasePointerCapture?.(e.pointerId);
|
|
1122
|
+
} catch {
|
|
1123
|
+
}
|
|
1124
|
+
draw.endStroke();
|
|
1125
|
+
};
|
|
1126
|
+
const handlePointerLeave = () => {
|
|
1127
|
+
setEraserPos(null);
|
|
1128
|
+
};
|
|
1129
|
+
const resolvedCursor = cursor ? cursor : spaceHeld ? "grab" : draw.tool === "eraser" ? "crosshair" : draw.tool === "pen" || draw.tool === "highlighter" ? "crosshair" : "default";
|
|
1130
|
+
const strokePath = draw.activeStroke ? strokePointsToPathData(draw.activeStroke.points) : null;
|
|
1131
|
+
const activeGradient = draw.activeStroke ? resolveCanvasGradient(draw.activeStroke.style.gradient ?? draw.activeStroke.style.color) : null;
|
|
1132
|
+
const resolvedGradientDef = activeGradient ? gradientToSvgDef(activeGradient, "active-draw-stroke-gradient") : null;
|
|
1133
|
+
const strokePaint = resolvedGradientDef ? `url(#${resolvedGradientDef.id})` : draw.activeStroke ? draw.activeStroke.style.color : "currentColor";
|
|
1134
|
+
return /* @__PURE__ */ jsxs3(
|
|
1135
|
+
"svg",
|
|
1136
|
+
{
|
|
1137
|
+
ref: svgRef,
|
|
1138
|
+
className: `pixerate-canvas-draw-layer ${className}`,
|
|
1139
|
+
style: {
|
|
1140
|
+
position: "absolute",
|
|
1141
|
+
inset: 0,
|
|
1142
|
+
width: "100%",
|
|
1143
|
+
height: "100%",
|
|
1144
|
+
pointerEvents: interactive ? "all" : "none",
|
|
1145
|
+
cursor: interactive ? resolvedCursor : void 0,
|
|
1146
|
+
overflow: "visible",
|
|
1147
|
+
zIndex: 20,
|
|
1148
|
+
touchAction: "none",
|
|
1149
|
+
...style
|
|
1150
|
+
},
|
|
1151
|
+
onPointerDown: handlePointerDown,
|
|
1152
|
+
onPointerMove: handlePointerMove,
|
|
1153
|
+
onPointerUp: handlePointerUp,
|
|
1154
|
+
onPointerLeave: handlePointerLeave,
|
|
1155
|
+
children: [
|
|
1156
|
+
resolvedGradientDef && /* @__PURE__ */ jsxs3("defs", { children: [
|
|
1157
|
+
resolvedGradientDef.type === "linear" && /* @__PURE__ */ jsx3("linearGradient", { id: resolvedGradientDef.id, ...resolvedGradientDef.attrs, children: resolvedGradientDef.stops.map((stop, i) => /* @__PURE__ */ jsx3("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
|
|
1158
|
+
resolvedGradientDef.type === "radial" && /* @__PURE__ */ jsx3("radialGradient", { id: resolvedGradientDef.id, ...resolvedGradientDef.attrs, children: resolvedGradientDef.stops.map((stop, i) => /* @__PURE__ */ jsx3("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) })
|
|
1159
|
+
] }),
|
|
1160
|
+
/* @__PURE__ */ jsx3("g", { transform: `translate(${viewport.x}, ${viewport.y}) scale(${viewport.zoom})`, children: draw.activeStroke && strokePath && /* @__PURE__ */ jsx3(
|
|
1161
|
+
"path",
|
|
1162
|
+
{
|
|
1163
|
+
className: "pixerate-canvas-draw-active",
|
|
1164
|
+
d: strokePath,
|
|
1165
|
+
fill: "none",
|
|
1166
|
+
stroke: strokePaint,
|
|
1167
|
+
strokeWidth: draw.activeStroke.style.width,
|
|
1168
|
+
opacity: draw.activeStroke.style.opacity,
|
|
1169
|
+
strokeLinecap: draw.activeStroke.style.cap ?? "round",
|
|
1170
|
+
strokeLinejoin: draw.activeStroke.style.join ?? "round"
|
|
1171
|
+
}
|
|
1172
|
+
) }),
|
|
1173
|
+
draw.tool === "eraser" && eraserPos && svgRef.current && /* @__PURE__ */ jsx3(
|
|
1174
|
+
"circle",
|
|
1175
|
+
{
|
|
1176
|
+
cx: eraserPos[0] - svgRef.current.getBoundingClientRect().left,
|
|
1177
|
+
cy: eraserPos[1] - svgRef.current.getBoundingClientRect().top,
|
|
1178
|
+
r: eraserRadius,
|
|
1179
|
+
fill: "rgba(239, 68, 68, 0.15)",
|
|
1180
|
+
stroke: "rgba(239, 68, 68, 0.8)",
|
|
1181
|
+
strokeWidth: 1.5,
|
|
1182
|
+
strokeDasharray: "3 3",
|
|
1183
|
+
pointerEvents: "none"
|
|
1184
|
+
}
|
|
1185
|
+
)
|
|
1186
|
+
]
|
|
1187
|
+
}
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
|
|
979
1191
|
// src/canvas/useCanvasMeasure.ts
|
|
980
|
-
import { useCallback as
|
|
1192
|
+
import { useCallback as useCallback8, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef9, useState as useState5 } from "react";
|
|
981
1193
|
import {
|
|
982
1194
|
isMeasureModifierHeld,
|
|
983
1195
|
measureSelection
|
|
@@ -985,11 +1197,11 @@ import {
|
|
|
985
1197
|
var EMPTY = { guides: [], target: null, selection: null };
|
|
986
1198
|
function useCanvasMeasure(options) {
|
|
987
1199
|
const { nodes, enabled = true, requireModifier = true, targetElement, rectOptions } = options;
|
|
988
|
-
const [hoveredId, setHoveredId] =
|
|
989
|
-
const [modifier, setModifier] =
|
|
990
|
-
const optionsRef =
|
|
1200
|
+
const [hoveredId, setHoveredId] = useState5(null);
|
|
1201
|
+
const [modifier, setModifier] = useState5(false);
|
|
1202
|
+
const optionsRef = useRef9(options);
|
|
991
1203
|
optionsRef.current = options;
|
|
992
|
-
|
|
1204
|
+
useEffect6(() => {
|
|
993
1205
|
if (!enabled) return;
|
|
994
1206
|
const target = targetElement ?? (typeof window !== "undefined" ? window : null);
|
|
995
1207
|
if (!target) return;
|
|
@@ -1006,16 +1218,16 @@ function useCanvasMeasure(options) {
|
|
|
1006
1218
|
};
|
|
1007
1219
|
}, [enabled, targetElement]);
|
|
1008
1220
|
const active = enabled && (!requireModifier || modifier);
|
|
1009
|
-
const result =
|
|
1221
|
+
const result = useMemo4(() => {
|
|
1010
1222
|
if (!active) return EMPTY;
|
|
1011
1223
|
const ids = optionsRef.current.getSelectedIds?.() ?? nodes.filter((n) => n.selected).map((n) => n.id);
|
|
1012
1224
|
return measureSelection(nodes, ids, hoveredId, rectOptions);
|
|
1013
1225
|
}, [active, nodes, hoveredId, rectOptions]);
|
|
1014
|
-
const onNodeMouseEnter =
|
|
1226
|
+
const onNodeMouseEnter = useCallback8((event, node) => {
|
|
1015
1227
|
setHoveredId(node.id);
|
|
1016
1228
|
if (event && typeof event.altKey === "boolean") setModifier(event.altKey);
|
|
1017
1229
|
}, []);
|
|
1018
|
-
const onNodeMouseLeave =
|
|
1230
|
+
const onNodeMouseLeave = useCallback8((_event, node) => {
|
|
1019
1231
|
setHoveredId((current) => current === node.id ? null : current);
|
|
1020
1232
|
}, []);
|
|
1021
1233
|
return {
|
|
@@ -1094,12 +1306,12 @@ import {
|
|
|
1094
1306
|
|
|
1095
1307
|
// src/canvas/ShapeNode.tsx
|
|
1096
1308
|
import { getShapeRenderData, isShapeDescription } from "@pixerate/editor/canvas";
|
|
1097
|
-
import { jsx as
|
|
1098
|
-
function ShapeNode({ data, width, height, selected, className = "", children }) {
|
|
1309
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1310
|
+
function ShapeNode({ id, data, width, height, selected, className = "", children }) {
|
|
1099
1311
|
const shape = data?.shape;
|
|
1100
1312
|
if (!isShapeDescription(shape)) return null;
|
|
1101
|
-
const render = getShapeRenderData(shape, { width, height });
|
|
1102
|
-
return /* @__PURE__ */
|
|
1313
|
+
const render = getShapeRenderData(shape, { width, height }, { id: id || data?.id });
|
|
1314
|
+
return /* @__PURE__ */ jsxs4(
|
|
1103
1315
|
"div",
|
|
1104
1316
|
{
|
|
1105
1317
|
className: `pixerate-shape-node ${className}`.trim(),
|
|
@@ -1107,7 +1319,7 @@ function ShapeNode({ data, width, height, selected, className = "", children })
|
|
|
1107
1319
|
"data-selected": selected ? "true" : void 0,
|
|
1108
1320
|
style: { position: "relative", width: "100%", height: "100%" },
|
|
1109
1321
|
children: [
|
|
1110
|
-
/* @__PURE__ */
|
|
1322
|
+
/* @__PURE__ */ jsxs4(
|
|
1111
1323
|
"svg",
|
|
1112
1324
|
{
|
|
1113
1325
|
viewBox: render.viewBox,
|
|
@@ -1116,19 +1328,29 @@ function ShapeNode({ data, width, height, selected, className = "", children })
|
|
|
1116
1328
|
height: "100%",
|
|
1117
1329
|
style: { display: "block", overflow: "visible" },
|
|
1118
1330
|
"aria-hidden": "true",
|
|
1119
|
-
children:
|
|
1120
|
-
"
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1331
|
+
children: [
|
|
1332
|
+
(render.fillGradient || render.strokeGradient) && /* @__PURE__ */ jsxs4("defs", { children: [
|
|
1333
|
+
render.fillGradient && render.fillGradient.type === "linear" && /* @__PURE__ */ jsx4("linearGradient", { id: render.fillGradient.id, ...render.fillGradient.attrs, children: render.fillGradient.stops.map((stop, i) => /* @__PURE__ */ jsx4("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
|
|
1334
|
+
render.fillGradient && render.fillGradient.type === "radial" && /* @__PURE__ */ jsx4("radialGradient", { id: render.fillGradient.id, ...render.fillGradient.attrs, children: render.fillGradient.stops.map((stop, i) => /* @__PURE__ */ jsx4("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
|
|
1335
|
+
render.strokeGradient && render.strokeGradient.type === "linear" && /* @__PURE__ */ jsx4("linearGradient", { id: render.strokeGradient.id, ...render.strokeGradient.attrs, children: render.strokeGradient.stops.map((stop, i) => /* @__PURE__ */ jsx4("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
|
|
1336
|
+
render.strokeGradient && render.strokeGradient.type === "radial" && /* @__PURE__ */ jsx4("radialGradient", { id: render.strokeGradient.id, ...render.strokeGradient.attrs, children: render.strokeGradient.stops.map((stop, i) => /* @__PURE__ */ jsx4("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) })
|
|
1337
|
+
] }),
|
|
1338
|
+
/* @__PURE__ */ jsx4(
|
|
1339
|
+
"path",
|
|
1340
|
+
{
|
|
1341
|
+
d: render.d,
|
|
1342
|
+
transform: render.transform,
|
|
1343
|
+
fill: render.fill,
|
|
1344
|
+
fillRule: render.fillRule,
|
|
1345
|
+
stroke: render.stroke,
|
|
1346
|
+
strokeWidth: render.strokeWidth,
|
|
1347
|
+
strokeLinecap: render.strokeLinecap,
|
|
1348
|
+
strokeLinejoin: render.strokeLinejoin,
|
|
1349
|
+
opacity: render.opacity,
|
|
1350
|
+
vectorEffect: "non-scaling-stroke"
|
|
1351
|
+
}
|
|
1352
|
+
)
|
|
1353
|
+
]
|
|
1132
1354
|
}
|
|
1133
1355
|
),
|
|
1134
1356
|
children
|
|
@@ -1264,17 +1486,17 @@ import {
|
|
|
1264
1486
|
} from "@pixerate/editor/canvas";
|
|
1265
1487
|
|
|
1266
1488
|
// src/canvas/useCanvasAutoLayout.ts
|
|
1267
|
-
import { useLayoutEffect, useMemo as
|
|
1489
|
+
import { useLayoutEffect, useMemo as useMemo5, useRef as useRef10, useState as useState6 } from "react";
|
|
1268
1490
|
import {
|
|
1269
1491
|
createCanvasAutoLayoutController
|
|
1270
1492
|
} from "@pixerate/editor/canvas";
|
|
1271
1493
|
function useCanvasAutoLayout(options) {
|
|
1272
|
-
const [guides, setGuides] =
|
|
1273
|
-
const nodesRef =
|
|
1494
|
+
const [guides, setGuides] = useState6([]);
|
|
1495
|
+
const nodesRef = useRef10(options.nodes);
|
|
1274
1496
|
nodesRef.current = options.nodes;
|
|
1275
|
-
const optionsRef =
|
|
1497
|
+
const optionsRef = useRef10(options);
|
|
1276
1498
|
optionsRef.current = options;
|
|
1277
|
-
const controller =
|
|
1499
|
+
const controller = useMemo5(
|
|
1278
1500
|
() => createCanvasAutoLayoutController({
|
|
1279
1501
|
getNodes: () => nodesRef.current,
|
|
1280
1502
|
setNodes: (next) => {
|
|
@@ -1303,7 +1525,7 @@ function useCanvasAutoLayout(options) {
|
|
|
1303
1525
|
useLayoutEffect(() => {
|
|
1304
1526
|
if (controller.hasPending) controller.flush();
|
|
1305
1527
|
}, [options.nodes, controller]);
|
|
1306
|
-
return
|
|
1528
|
+
return useMemo5(
|
|
1307
1529
|
() => ({
|
|
1308
1530
|
...controller,
|
|
1309
1531
|
/** Drop marker of the active reorder drag (flow coordinates). */
|
|
@@ -1317,7 +1539,7 @@ function useCanvasAutoLayout(options) {
|
|
|
1317
1539
|
}
|
|
1318
1540
|
|
|
1319
1541
|
// src/canvas/useCanvasTokens.ts
|
|
1320
|
-
import { useCallback as
|
|
1542
|
+
import { useCallback as useCallback9, useEffect as useEffect7, useRef as useRef11, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
1321
1543
|
import {
|
|
1322
1544
|
bindCanvasToken,
|
|
1323
1545
|
detachTokenBindings,
|
|
@@ -1328,10 +1550,10 @@ import {
|
|
|
1328
1550
|
function useCanvasTokens(options) {
|
|
1329
1551
|
const { store, nodes, setNodes, modes, properties } = options;
|
|
1330
1552
|
const state = useSyncExternalStore2(store.subscribe, store.getState, store.getState);
|
|
1331
|
-
const latest =
|
|
1553
|
+
const latest = useRef11({ nodes, setNodes, modes, properties });
|
|
1332
1554
|
latest.current = { nodes, setNodes, modes, properties };
|
|
1333
1555
|
const opts = () => ({ modes: latest.current.modes, properties: latest.current.properties });
|
|
1334
|
-
|
|
1556
|
+
useEffect7(
|
|
1335
1557
|
() => store.subscribe((event) => {
|
|
1336
1558
|
if (event.deletedVariableIds.length === 0) return;
|
|
1337
1559
|
latest.current.setNodes((prev) => detachTokenBindings(prev, event.previous, event.deletedVariableIds, opts()));
|
|
@@ -1340,11 +1562,11 @@ function useCanvasTokens(options) {
|
|
|
1340
1562
|
[store]
|
|
1341
1563
|
);
|
|
1342
1564
|
const modesKey = JSON.stringify(modes ?? {});
|
|
1343
|
-
|
|
1565
|
+
useEffect7(() => {
|
|
1344
1566
|
const next = resolveCanvasTokens(nodes, state, opts());
|
|
1345
1567
|
if (next !== nodes) setNodes(next);
|
|
1346
1568
|
}, [nodes, state, modesKey, properties]);
|
|
1347
|
-
const bind =
|
|
1569
|
+
const bind = useCallback9(
|
|
1348
1570
|
(ids, propertyKey, variableId) => {
|
|
1349
1571
|
const next = bindCanvasToken(latest.current.nodes, ids, propertyKey, variableId, store.getState(), opts());
|
|
1350
1572
|
if (next !== latest.current.nodes) latest.current.setNodes(next);
|
|
@@ -1352,7 +1574,7 @@ function useCanvasTokens(options) {
|
|
|
1352
1574
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1353
1575
|
[store]
|
|
1354
1576
|
);
|
|
1355
|
-
const setMode =
|
|
1577
|
+
const setMode = useCallback9(
|
|
1356
1578
|
(ids, collectionId, modeId) => {
|
|
1357
1579
|
const next = setCanvasTokenMode(latest.current.nodes, ids, collectionId, modeId, store.getState(), opts());
|
|
1358
1580
|
if (next !== latest.current.nodes) latest.current.setNodes(next);
|
|
@@ -1360,7 +1582,7 @@ function useCanvasTokens(options) {
|
|
|
1360
1582
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1361
1583
|
[store]
|
|
1362
1584
|
);
|
|
1363
|
-
const modesOf =
|
|
1585
|
+
const modesOf = useCallback9(
|
|
1364
1586
|
(nodeId) => {
|
|
1365
1587
|
const node = latest.current.nodes.find((n) => n.id === nodeId);
|
|
1366
1588
|
return node ? getEffectiveTokenModes(node, latest.current.nodes, store.getState(), opts()) : {};
|
|
@@ -1382,7 +1604,7 @@ import {
|
|
|
1382
1604
|
getTokensForProperty
|
|
1383
1605
|
} from "@pixerate/editor/canvas";
|
|
1384
1606
|
import { getCurrentMode, resolveToken } from "@pixerate/editor/tokens";
|
|
1385
|
-
import { jsx as
|
|
1607
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1386
1608
|
function TokenBindingPicker({
|
|
1387
1609
|
state,
|
|
1388
1610
|
nodes,
|
|
@@ -1399,15 +1621,15 @@ function TokenBindingPicker({
|
|
|
1399
1621
|
let rows = getBindableTokenProperties(first, options);
|
|
1400
1622
|
if (properties) rows = properties.map((key) => rows.find((p) => p.key === key)).filter((p) => !!p);
|
|
1401
1623
|
const modes = getEffectiveTokenModes2(first, nodes, state, options);
|
|
1402
|
-
return /* @__PURE__ */
|
|
1624
|
+
return /* @__PURE__ */ jsxs5("div", { "data-token-binding-picker": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
|
|
1403
1625
|
rows.map((property) => {
|
|
1404
1626
|
const ids = new Set(selected.map((n) => getNodeTokenBindings(n)[property.key] ?? ""));
|
|
1405
1627
|
const value = ids.size === 1 ? [...ids][0] : "__mixed";
|
|
1406
1628
|
const candidates = getTokensForProperty(state, property, first);
|
|
1407
1629
|
const resolved = value && value !== "__mixed" ? resolveToken(state, value, modes) : null;
|
|
1408
|
-
return /* @__PURE__ */
|
|
1409
|
-
/* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1630
|
+
return /* @__PURE__ */ jsxs5("label", { className: "flex items-center gap-2", "data-token-property": property.key, children: [
|
|
1631
|
+
/* @__PURE__ */ jsx5("span", { className: "w-28 shrink-0 text-muted-foreground", children: property.label }),
|
|
1632
|
+
/* @__PURE__ */ jsxs5(
|
|
1411
1633
|
"select",
|
|
1412
1634
|
{
|
|
1413
1635
|
"aria-label": `${property.label} variable`,
|
|
@@ -1422,11 +1644,11 @@ function TokenBindingPicker({
|
|
|
1422
1644
|
}
|
|
1423
1645
|
},
|
|
1424
1646
|
children: [
|
|
1425
|
-
value === "__mixed" ? /* @__PURE__ */
|
|
1426
|
-
/* @__PURE__ */
|
|
1647
|
+
value === "__mixed" ? /* @__PURE__ */ jsx5("option", { value: "__mixed", children: "Mixed" }) : null,
|
|
1648
|
+
/* @__PURE__ */ jsx5("option", { value: "", children: "None" }),
|
|
1427
1649
|
candidates.map((v) => {
|
|
1428
1650
|
const collection = state.collections.find((c) => c.id === v.collectionId);
|
|
1429
|
-
return /* @__PURE__ */
|
|
1651
|
+
return /* @__PURE__ */ jsxs5("option", { value: v.id, children: [
|
|
1430
1652
|
v.name,
|
|
1431
1653
|
collection && state.collections.length > 1 ? ` (${collection.name})` : ""
|
|
1432
1654
|
] }, v.id);
|
|
@@ -1434,17 +1656,17 @@ function TokenBindingPicker({
|
|
|
1434
1656
|
]
|
|
1435
1657
|
}
|
|
1436
1658
|
),
|
|
1437
|
-
/* @__PURE__ */
|
|
1659
|
+
/* @__PURE__ */ jsx5("span", { className: "w-16 shrink-0 truncate text-right text-muted-foreground", "data-token-resolved": "", children: resolved?.ok ? property.type === "color" ? /* @__PURE__ */ jsx5(
|
|
1438
1660
|
"span",
|
|
1439
1661
|
{
|
|
1440
1662
|
className: "inline-block h-3 w-3 rounded border border-border align-middle",
|
|
1441
1663
|
style: { background: String(resolved.value) },
|
|
1442
1664
|
title: String(resolved.value)
|
|
1443
1665
|
}
|
|
1444
|
-
) : String(resolved.value) : resolved ? /* @__PURE__ */
|
|
1666
|
+
) : String(resolved.value) : resolved ? /* @__PURE__ */ jsx5("span", { title: resolved.message, children: "\u26A0" }) : null })
|
|
1445
1667
|
] }, property.key);
|
|
1446
1668
|
}),
|
|
1447
|
-
state.collections.length === 0 ? /* @__PURE__ */
|
|
1669
|
+
state.collections.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-muted-foreground", children: "No variables yet." }) : null
|
|
1448
1670
|
] });
|
|
1449
1671
|
}
|
|
1450
1672
|
function TokenModeSwitcher({
|
|
@@ -1462,12 +1684,12 @@ function TokenModeSwitcher({
|
|
|
1462
1684
|
const parent = first.parentId ? nodes.find((n) => n.id === first.parentId) : void 0;
|
|
1463
1685
|
const inherited = parent ? getEffectiveTokenModes2(parent, nodes, state, options) : { ...options.modes };
|
|
1464
1686
|
const collections = state.collections.filter((c) => showSingleMode || c.modes.length > 1);
|
|
1465
|
-
return /* @__PURE__ */
|
|
1687
|
+
return /* @__PURE__ */ jsx5("div", { "data-token-mode-switcher": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: collections.map((collection) => {
|
|
1466
1688
|
const auto = getCurrentMode(collection, inherited);
|
|
1467
1689
|
const explicit = collection.modes.some((m) => m.id === own[collection.id]) ? own[collection.id] : "";
|
|
1468
|
-
return /* @__PURE__ */
|
|
1469
|
-
/* @__PURE__ */
|
|
1470
|
-
/* @__PURE__ */
|
|
1690
|
+
return /* @__PURE__ */ jsxs5("label", { className: "flex items-center gap-2", "data-token-collection": collection.id, children: [
|
|
1691
|
+
/* @__PURE__ */ jsx5("span", { className: "w-28 shrink-0 truncate text-muted-foreground", children: collection.name }),
|
|
1692
|
+
/* @__PURE__ */ jsxs5(
|
|
1471
1693
|
"select",
|
|
1472
1694
|
{
|
|
1473
1695
|
"aria-label": `${collection.name} mode`,
|
|
@@ -1475,12 +1697,12 @@ function TokenModeSwitcher({
|
|
|
1475
1697
|
value: explicit,
|
|
1476
1698
|
onChange: (e) => onChange(setCanvasTokenMode2(nodes, nodeIds, collection.id, e.currentTarget.value || null, state, options)),
|
|
1477
1699
|
children: [
|
|
1478
|
-
/* @__PURE__ */
|
|
1700
|
+
/* @__PURE__ */ jsxs5("option", { value: "", children: [
|
|
1479
1701
|
"Auto (",
|
|
1480
1702
|
auto.name,
|
|
1481
1703
|
")"
|
|
1482
1704
|
] }),
|
|
1483
|
-
collection.modes.map((m) => /* @__PURE__ */
|
|
1705
|
+
collection.modes.map((m) => /* @__PURE__ */ jsx5("option", { value: m.id, children: m.name }, m.id))
|
|
1484
1706
|
]
|
|
1485
1707
|
}
|
|
1486
1708
|
)
|
|
@@ -1511,16 +1733,16 @@ import {
|
|
|
1511
1733
|
} from "@pixerate/editor/canvas";
|
|
1512
1734
|
|
|
1513
1735
|
// src/canvas/useCanvasAnimation.ts
|
|
1514
|
-
import { useEffect as
|
|
1736
|
+
import { useEffect as useEffect8, useMemo as useMemo6, useRef as useRef12, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
1515
1737
|
import {
|
|
1516
1738
|
createCanvasAnimationController
|
|
1517
1739
|
} from "@pixerate/editor/canvas";
|
|
1518
1740
|
function useCanvasAnimation(options) {
|
|
1519
|
-
const nodesRef =
|
|
1741
|
+
const nodesRef = useRef12(options.nodes);
|
|
1520
1742
|
nodesRef.current = options.nodes;
|
|
1521
|
-
const optionsRef =
|
|
1743
|
+
const optionsRef = useRef12(options);
|
|
1522
1744
|
optionsRef.current = options;
|
|
1523
|
-
const controller =
|
|
1745
|
+
const controller = useMemo6(
|
|
1524
1746
|
() => createCanvasAnimationController({
|
|
1525
1747
|
getNodes: () => nodesRef.current,
|
|
1526
1748
|
setNodes: (next) => {
|
|
@@ -1547,14 +1769,14 @@ function useCanvasAnimation(options) {
|
|
|
1547
1769
|
}),
|
|
1548
1770
|
[]
|
|
1549
1771
|
);
|
|
1550
|
-
|
|
1551
|
-
|
|
1772
|
+
useEffect8(() => () => controller.destroy(), [controller]);
|
|
1773
|
+
useEffect8(() => {
|
|
1552
1774
|
if (options.loop !== void 0) controller.setLoop(options.loop);
|
|
1553
1775
|
}, [controller, options.loop]);
|
|
1554
|
-
|
|
1776
|
+
useEffect8(() => {
|
|
1555
1777
|
if (options.playbackRate !== void 0) controller.setPlaybackRate(options.playbackRate);
|
|
1556
1778
|
}, [controller, options.playbackRate]);
|
|
1557
|
-
|
|
1779
|
+
useEffect8(() => {
|
|
1558
1780
|
if (options.recording !== void 0) controller.setRecording(options.recording);
|
|
1559
1781
|
}, [controller, options.recording]);
|
|
1560
1782
|
const state = useSyncExternalStore3(
|
|
@@ -1562,11 +1784,11 @@ function useCanvasAnimation(options) {
|
|
|
1562
1784
|
() => controller.getState(),
|
|
1563
1785
|
() => controller.getState()
|
|
1564
1786
|
);
|
|
1565
|
-
|
|
1787
|
+
useEffect8(() => {
|
|
1566
1788
|
controller.refresh();
|
|
1567
1789
|
}, [controller, options.nodes]);
|
|
1568
|
-
const displayNodes =
|
|
1569
|
-
return
|
|
1790
|
+
const displayNodes = useMemo6(() => controller.display(options.nodes), [controller, options.nodes, state.time]);
|
|
1791
|
+
return useMemo6(
|
|
1570
1792
|
() => ({
|
|
1571
1793
|
...controller,
|
|
1572
1794
|
state,
|
|
@@ -1587,7 +1809,7 @@ function useCanvasAnimation(options) {
|
|
|
1587
1809
|
}
|
|
1588
1810
|
|
|
1589
1811
|
// src/canvas/AnimationTimeline.tsx
|
|
1590
|
-
import { useEffect as
|
|
1812
|
+
import { useEffect as useEffect9, useRef as useRef13 } from "react";
|
|
1591
1813
|
import {
|
|
1592
1814
|
ANIMATION_EASING_LABELS,
|
|
1593
1815
|
ANIMATION_EASING_PRESETS,
|
|
@@ -1596,7 +1818,7 @@ import {
|
|
|
1596
1818
|
timeToX,
|
|
1597
1819
|
xToTime
|
|
1598
1820
|
} from "@pixerate/editor/canvas";
|
|
1599
|
-
import { jsx as
|
|
1821
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1600
1822
|
var LOOP_LABELS = { none: "Once", loop: "Loop", "ping-pong": "Ping-pong" };
|
|
1601
1823
|
var easingValue = (easing) => typeof easing === "string" ? easing : easing ? "custom" : "linear";
|
|
1602
1824
|
function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8, labelOf, className = "" }) {
|
|
@@ -1610,8 +1832,8 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
|
|
|
1610
1832
|
for (const row of rows) for (const k of row.keyframes) if (k.selected && k.ref.property === first.property && k.ref.nodeId === first.nodeId) return easingValue(k.easing);
|
|
1611
1833
|
return "";
|
|
1612
1834
|
})();
|
|
1613
|
-
const dragRef =
|
|
1614
|
-
|
|
1835
|
+
const dragRef = useRef13(null);
|
|
1836
|
+
useEffect9(() => {
|
|
1615
1837
|
const onKey = (event) => {
|
|
1616
1838
|
if (event.key === "Escape" && dragRef.current) {
|
|
1617
1839
|
dragRef.current = null;
|
|
@@ -1667,10 +1889,10 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
|
|
|
1667
1889
|
const btn = "rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-50";
|
|
1668
1890
|
const playheadX = timeToX(state.time, duration, width);
|
|
1669
1891
|
const labelWidth = 120;
|
|
1670
|
-
return /* @__PURE__ */
|
|
1671
|
-
/* @__PURE__ */
|
|
1672
|
-
/* @__PURE__ */
|
|
1673
|
-
/* @__PURE__ */
|
|
1892
|
+
return /* @__PURE__ */ jsxs6("div", { "data-animation-timeline": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, tabIndex: 0, onKeyDown: onTimelineKey, children: [
|
|
1893
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-wrap items-center gap-2", role: "toolbar", "aria-label": "Animation", children: [
|
|
1894
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: btn, "data-action": "toggle-play", "aria-label": state.playing ? "Pause" : "Play", onClick: () => animation.toggle(), children: state.playing ? "\u275A\u275A" : "\u25B6" }),
|
|
1895
|
+
/* @__PURE__ */ jsx6(
|
|
1674
1896
|
"button",
|
|
1675
1897
|
{
|
|
1676
1898
|
type: "button",
|
|
@@ -1682,13 +1904,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
|
|
|
1682
1904
|
children: "\u25CF Rec"
|
|
1683
1905
|
}
|
|
1684
1906
|
),
|
|
1685
|
-
/* @__PURE__ */
|
|
1686
|
-
/* @__PURE__ */
|
|
1907
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: btn, "data-action": "add-keyframe", onClick: () => animation.addKeyframe(), children: "\u25C6 Key" }),
|
|
1908
|
+
/* @__PURE__ */ jsxs6("span", { "data-time": "", className: "tabular-nums text-muted-foreground", children: [
|
|
1687
1909
|
formatAnimationTime(state.time),
|
|
1688
1910
|
" / ",
|
|
1689
1911
|
formatAnimationTime(duration)
|
|
1690
1912
|
] }),
|
|
1691
|
-
/* @__PURE__ */
|
|
1913
|
+
/* @__PURE__ */ jsxs6(
|
|
1692
1914
|
"select",
|
|
1693
1915
|
{
|
|
1694
1916
|
"aria-label": "Easing",
|
|
@@ -1698,13 +1920,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
|
|
|
1698
1920
|
disabled: state.selection.length === 0,
|
|
1699
1921
|
onChange: (e) => e.target.value && e.target.value !== "custom" && animation.setEasing(e.target.value),
|
|
1700
1922
|
children: [
|
|
1701
|
-
/* @__PURE__ */
|
|
1702
|
-
ANIMATION_EASING_PRESETS.map((preset) => /* @__PURE__ */
|
|
1703
|
-
selectedEasing === "custom" ? /* @__PURE__ */
|
|
1923
|
+
/* @__PURE__ */ jsx6("option", { value: "", children: "Easing\u2026" }),
|
|
1924
|
+
ANIMATION_EASING_PRESETS.map((preset) => /* @__PURE__ */ jsx6("option", { value: preset, children: ANIMATION_EASING_LABELS[preset] }, preset)),
|
|
1925
|
+
selectedEasing === "custom" ? /* @__PURE__ */ jsx6("option", { value: "custom", children: "Custom" }) : null
|
|
1704
1926
|
]
|
|
1705
1927
|
}
|
|
1706
1928
|
),
|
|
1707
|
-
/* @__PURE__ */
|
|
1929
|
+
/* @__PURE__ */ jsx6(
|
|
1708
1930
|
"select",
|
|
1709
1931
|
{
|
|
1710
1932
|
"aria-label": "Loop",
|
|
@@ -1712,13 +1934,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
|
|
|
1712
1934
|
className: "rounded border border-border bg-background px-1 py-0.5",
|
|
1713
1935
|
value: state.loop,
|
|
1714
1936
|
onChange: (e) => animation.setLoop(e.target.value),
|
|
1715
|
-
children: Object.keys(LOOP_LABELS).map((mode) => /* @__PURE__ */
|
|
1937
|
+
children: Object.keys(LOOP_LABELS).map((mode) => /* @__PURE__ */ jsx6("option", { value: mode, children: LOOP_LABELS[mode] }, mode))
|
|
1716
1938
|
}
|
|
1717
1939
|
)
|
|
1718
1940
|
] }),
|
|
1719
|
-
/* @__PURE__ */
|
|
1720
|
-
/* @__PURE__ */
|
|
1721
|
-
/* @__PURE__ */
|
|
1941
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex", children: [
|
|
1942
|
+
/* @__PURE__ */ jsx6("div", { style: { width: labelWidth }, className: "shrink-0" }),
|
|
1943
|
+
/* @__PURE__ */ jsxs6(
|
|
1722
1944
|
"div",
|
|
1723
1945
|
{
|
|
1724
1946
|
"data-timeline-ruler": "",
|
|
@@ -1726,15 +1948,15 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
|
|
|
1726
1948
|
style: { width },
|
|
1727
1949
|
onPointerDown: onRulerDown,
|
|
1728
1950
|
children: [
|
|
1729
|
-
ticks.map((tick) => /* @__PURE__ */
|
|
1730
|
-
/* @__PURE__ */
|
|
1951
|
+
ticks.map((tick) => /* @__PURE__ */ jsx6("span", { className: "absolute top-0 -translate-x-1/2 text-[10px] text-muted-foreground", style: { left: tick.x }, children: tick.label }, tick.time)),
|
|
1952
|
+
/* @__PURE__ */ jsx6("div", { "data-playhead": "", className: "absolute top-0 h-5 w-px bg-red-500", style: { left: playheadX } })
|
|
1731
1953
|
]
|
|
1732
1954
|
}
|
|
1733
1955
|
)
|
|
1734
1956
|
] }),
|
|
1735
|
-
rows.length === 0 ? /* @__PURE__ */
|
|
1736
|
-
/* @__PURE__ */
|
|
1737
|
-
/* @__PURE__ */
|
|
1957
|
+
rows.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground", "data-timeline-empty": "", children: "Select an animated node, or press \u25C6 Key to add a keyframe." }) : rows.map((row) => /* @__PURE__ */ jsxs6("div", { className: "flex items-center", "data-track": row.id, children: [
|
|
1958
|
+
/* @__PURE__ */ jsxs6("label", { className: "flex shrink-0 items-center gap-1 truncate pr-2", style: { width: labelWidth }, title: `${row.nodeLabel} \xB7 ${row.label}`, children: [
|
|
1959
|
+
/* @__PURE__ */ jsx6(
|
|
1738
1960
|
"input",
|
|
1739
1961
|
{
|
|
1740
1962
|
type: "checkbox",
|
|
@@ -1743,15 +1965,15 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
|
|
|
1743
1965
|
onChange: (e) => animation.setTrackEnabled(row.nodeId, row.property, e.target.checked)
|
|
1744
1966
|
}
|
|
1745
1967
|
),
|
|
1746
|
-
/* @__PURE__ */
|
|
1968
|
+
/* @__PURE__ */ jsxs6("span", { className: "truncate", children: [
|
|
1747
1969
|
rows.filter((r) => r.nodeId === row.nodeId).length < rows.length ? `${row.nodeLabel} \xB7 ` : "",
|
|
1748
1970
|
row.label
|
|
1749
1971
|
] })
|
|
1750
1972
|
] }),
|
|
1751
|
-
/* @__PURE__ */
|
|
1752
|
-
/* @__PURE__ */
|
|
1753
|
-
state.drag?.target != null ? /* @__PURE__ */
|
|
1754
|
-
row.keyframes.map((k) => /* @__PURE__ */
|
|
1973
|
+
/* @__PURE__ */ jsxs6("div", { "data-lane": "", className: `relative h-5 rounded bg-muted/40 ${row.enabled ? "" : "opacity-50"}`, style: { width }, children: [
|
|
1974
|
+
/* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute top-0 h-5 w-px bg-red-500/60", style: { left: playheadX } }),
|
|
1975
|
+
state.drag?.target != null ? /* @__PURE__ */ jsx6("div", { "data-snap-target": "", className: "pointer-events-none absolute top-0 h-5 w-px bg-sky-400", style: { left: timeToX(state.drag.target, duration, width) } }) : null,
|
|
1976
|
+
row.keyframes.map((k) => /* @__PURE__ */ jsx6(
|
|
1755
1977
|
"button",
|
|
1756
1978
|
{
|
|
1757
1979
|
type: "button",
|
|
@@ -1849,16 +2071,16 @@ import {
|
|
|
1849
2071
|
} from "@pixerate/editor/canvas";
|
|
1850
2072
|
|
|
1851
2073
|
// src/canvas/useCanvasComponents.ts
|
|
1852
|
-
import { useLayoutEffect as useLayoutEffect2, useMemo as
|
|
2074
|
+
import { useLayoutEffect as useLayoutEffect2, useMemo as useMemo7, useRef as useRef14 } from "react";
|
|
1853
2075
|
import {
|
|
1854
2076
|
createCanvasComponentsController
|
|
1855
2077
|
} from "@pixerate/editor/canvas";
|
|
1856
2078
|
function useCanvasComponents(options) {
|
|
1857
|
-
const nodesRef =
|
|
2079
|
+
const nodesRef = useRef14(options.nodes);
|
|
1858
2080
|
nodesRef.current = options.nodes;
|
|
1859
|
-
const optionsRef =
|
|
2081
|
+
const optionsRef = useRef14(options);
|
|
1860
2082
|
optionsRef.current = options;
|
|
1861
|
-
const controller =
|
|
2083
|
+
const controller = useMemo7(
|
|
1862
2084
|
() => createCanvasComponentsController({
|
|
1863
2085
|
getNodes: () => nodesRef.current,
|
|
1864
2086
|
setNodes: (next) => {
|
|
@@ -1894,15 +2116,15 @@ function useCanvasComponents(options) {
|
|
|
1894
2116
|
}
|
|
1895
2117
|
|
|
1896
2118
|
// src/canvas/CanvasComponentsPanel.tsx
|
|
1897
|
-
import { useState as
|
|
2119
|
+
import { useState as useState7 } from "react";
|
|
1898
2120
|
import {
|
|
1899
2121
|
CANVAS_COMPONENT_DRAG_TYPE,
|
|
1900
2122
|
inspectCanvasInstance,
|
|
1901
2123
|
listCanvasComponents
|
|
1902
2124
|
} from "@pixerate/editor/canvas";
|
|
1903
|
-
import { Fragment, jsx as
|
|
2125
|
+
import { Fragment, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1904
2126
|
function InlineField({ value, label, onCommit }) {
|
|
1905
|
-
return /* @__PURE__ */
|
|
2127
|
+
return /* @__PURE__ */ jsx7(
|
|
1906
2128
|
"input",
|
|
1907
2129
|
{
|
|
1908
2130
|
type: "text",
|
|
@@ -1933,10 +2155,10 @@ function CanvasComponentsPanel({
|
|
|
1933
2155
|
search = true,
|
|
1934
2156
|
className = ""
|
|
1935
2157
|
}) {
|
|
1936
|
-
const [query, setQuery] =
|
|
1937
|
-
const [propsOpen, setPropsOpen] =
|
|
1938
|
-
const [menuFor, setMenuFor] =
|
|
1939
|
-
const [editing, setEditing] =
|
|
2158
|
+
const [query, setQuery] = useState7("");
|
|
2159
|
+
const [propsOpen, setPropsOpen] = useState7(null);
|
|
2160
|
+
const [menuFor, setMenuFor] = useState7(null);
|
|
2161
|
+
const [editing, setEditing] = useState7(null);
|
|
1940
2162
|
const { components: all, sets } = listCanvasComponents(nodes);
|
|
1941
2163
|
const q = query.trim().toLowerCase();
|
|
1942
2164
|
const match = (name) => !q || name.toLowerCase().includes(q);
|
|
@@ -1948,7 +2170,7 @@ function CanvasComponentsPanel({
|
|
|
1948
2170
|
};
|
|
1949
2171
|
const small = "shrink-0 rounded px-1 text-[10px] text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-40";
|
|
1950
2172
|
const menuItem = "rounded px-2 py-0.5 text-left hover:bg-muted disabled:opacity-40";
|
|
1951
|
-
const item = (id, name, count, extra = {}, onContextMenu) => /* @__PURE__ */
|
|
2173
|
+
const item = (id, name, count, extra = {}, onContextMenu) => /* @__PURE__ */ jsxs7(
|
|
1952
2174
|
"button",
|
|
1953
2175
|
{
|
|
1954
2176
|
type: "button",
|
|
@@ -1965,17 +2187,17 @@ function CanvasComponentsPanel({
|
|
|
1965
2187
|
e.dataTransfer.effectAllowed = "copy";
|
|
1966
2188
|
},
|
|
1967
2189
|
children: [
|
|
1968
|
-
/* @__PURE__ */
|
|
1969
|
-
/* @__PURE__ */
|
|
2190
|
+
/* @__PURE__ */ jsxs7("span", { className: "truncate", children: [
|
|
2191
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": true, className: "mr-1 text-muted-foreground", children: "\u25C7" }),
|
|
1970
2192
|
name
|
|
1971
2193
|
] }),
|
|
1972
|
-
/* @__PURE__ */
|
|
2194
|
+
/* @__PURE__ */ jsx7("span", { className: "text-[10px] text-muted-foreground", "data-instance-count": "", children: count })
|
|
1973
2195
|
]
|
|
1974
2196
|
},
|
|
1975
2197
|
id
|
|
1976
2198
|
);
|
|
1977
|
-
return /* @__PURE__ */
|
|
1978
|
-
search ? /* @__PURE__ */
|
|
2199
|
+
return /* @__PURE__ */ jsxs7("div", { "data-components-panel": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
|
|
2200
|
+
search ? /* @__PURE__ */ jsx7(
|
|
1979
2201
|
"input",
|
|
1980
2202
|
{
|
|
1981
2203
|
type: "search",
|
|
@@ -1985,11 +2207,11 @@ function CanvasComponentsPanel({
|
|
|
1985
2207
|
onInput: (e) => setQuery(e.target.value)
|
|
1986
2208
|
}
|
|
1987
2209
|
) : null,
|
|
1988
|
-
shownSets.map((set) => /* @__PURE__ */
|
|
1989
|
-
/* @__PURE__ */
|
|
2210
|
+
shownSets.map((set) => /* @__PURE__ */ jsxs7("div", { "data-component-set": set.id, className: "flex flex-col", children: [
|
|
2211
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
|
|
1990
2212
|
item(set.id, set.name, set.variants.reduce((sum, v) => sum + v.instanceCount, 0), { "data-kind": "set" }),
|
|
1991
|
-
components ? /* @__PURE__ */
|
|
1992
|
-
/* @__PURE__ */
|
|
2213
|
+
components ? /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
2214
|
+
/* @__PURE__ */ jsx7(
|
|
1993
2215
|
"button",
|
|
1994
2216
|
{
|
|
1995
2217
|
type: "button",
|
|
@@ -2001,7 +2223,7 @@ function CanvasComponentsPanel({
|
|
|
2001
2223
|
children: "+\xA0Variant"
|
|
2002
2224
|
}
|
|
2003
2225
|
),
|
|
2004
|
-
/* @__PURE__ */
|
|
2226
|
+
/* @__PURE__ */ jsx7(
|
|
2005
2227
|
"button",
|
|
2006
2228
|
{
|
|
2007
2229
|
type: "button",
|
|
@@ -2016,8 +2238,8 @@ function CanvasComponentsPanel({
|
|
|
2016
2238
|
)
|
|
2017
2239
|
] }) : null
|
|
2018
2240
|
] }),
|
|
2019
|
-
components && propsOpen === set.id ? /* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2241
|
+
components && propsOpen === set.id ? /* @__PURE__ */ jsx7("div", { "data-variant-properties": set.id, className: "ml-3 flex flex-col gap-1 border-l border-border py-1 pl-2", children: set.options.map((option) => /* @__PURE__ */ jsxs7("div", { "data-variant-option": option.name, className: "flex flex-col gap-0.5", children: [
|
|
2242
|
+
/* @__PURE__ */ jsx7(
|
|
2021
2243
|
InlineField,
|
|
2022
2244
|
{
|
|
2023
2245
|
value: option.name,
|
|
@@ -2025,7 +2247,7 @@ function CanvasComponentsPanel({
|
|
|
2025
2247
|
onCommit: (next) => report(components.renameVariantProperty(option.name, next, set.id))
|
|
2026
2248
|
}
|
|
2027
2249
|
),
|
|
2028
|
-
/* @__PURE__ */
|
|
2250
|
+
/* @__PURE__ */ jsx7("div", { className: "ml-2 flex flex-wrap gap-1", children: option.values.map((value) => /* @__PURE__ */ jsx7(
|
|
2029
2251
|
InlineField,
|
|
2030
2252
|
{
|
|
2031
2253
|
value,
|
|
@@ -2035,8 +2257,8 @@ function CanvasComponentsPanel({
|
|
|
2035
2257
|
value
|
|
2036
2258
|
)) })
|
|
2037
2259
|
] }, option.name)) }) : null,
|
|
2038
|
-
/* @__PURE__ */
|
|
2039
|
-
/* @__PURE__ */
|
|
2260
|
+
/* @__PURE__ */ jsx7("div", { className: "ml-3 flex flex-col border-l border-border pl-1", children: set.variants.map((v) => /* @__PURE__ */ jsxs7("div", { "data-variant-row": v.id, className: "flex flex-col", children: [
|
|
2261
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
|
|
2040
2262
|
item(
|
|
2041
2263
|
v.id,
|
|
2042
2264
|
v.name,
|
|
@@ -2047,7 +2269,7 @@ function CanvasComponentsPanel({
|
|
|
2047
2269
|
setMenuFor(v.id);
|
|
2048
2270
|
} : void 0
|
|
2049
2271
|
),
|
|
2050
|
-
components ? /* @__PURE__ */
|
|
2272
|
+
components ? /* @__PURE__ */ jsx7(
|
|
2051
2273
|
"button",
|
|
2052
2274
|
{
|
|
2053
2275
|
type: "button",
|
|
@@ -2061,8 +2283,8 @@ function CanvasComponentsPanel({
|
|
|
2061
2283
|
}
|
|
2062
2284
|
) : null
|
|
2063
2285
|
] }),
|
|
2064
|
-
components && menuFor === v.id ? /* @__PURE__ */
|
|
2065
|
-
/* @__PURE__ */
|
|
2286
|
+
components && menuFor === v.id ? /* @__PURE__ */ jsxs7("div", { role: "menu", "data-variant-menu": v.id, className: "ml-2 flex flex-col rounded border border-border bg-background p-1 shadow", children: [
|
|
2287
|
+
/* @__PURE__ */ jsx7(
|
|
2066
2288
|
"button",
|
|
2067
2289
|
{
|
|
2068
2290
|
type: "button",
|
|
@@ -2076,7 +2298,7 @@ function CanvasComponentsPanel({
|
|
|
2076
2298
|
children: "Edit values\u2026"
|
|
2077
2299
|
}
|
|
2078
2300
|
),
|
|
2079
|
-
/* @__PURE__ */
|
|
2301
|
+
/* @__PURE__ */ jsx7(
|
|
2080
2302
|
"button",
|
|
2081
2303
|
{
|
|
2082
2304
|
type: "button",
|
|
@@ -2090,7 +2312,7 @@ function CanvasComponentsPanel({
|
|
|
2090
2312
|
children: "Duplicate"
|
|
2091
2313
|
}
|
|
2092
2314
|
),
|
|
2093
|
-
/* @__PURE__ */
|
|
2315
|
+
/* @__PURE__ */ jsx7(
|
|
2094
2316
|
"button",
|
|
2095
2317
|
{
|
|
2096
2318
|
type: "button",
|
|
@@ -2107,7 +2329,7 @@ function CanvasComponentsPanel({
|
|
|
2107
2329
|
}
|
|
2108
2330
|
)
|
|
2109
2331
|
] }) : null,
|
|
2110
|
-
components && editing === v.id ? /* @__PURE__ */
|
|
2332
|
+
components && editing === v.id ? /* @__PURE__ */ jsxs7(
|
|
2111
2333
|
"form",
|
|
2112
2334
|
{
|
|
2113
2335
|
"data-variant-editor": v.id,
|
|
@@ -2121,9 +2343,9 @@ function CanvasComponentsPanel({
|
|
|
2121
2343
|
if (report(components.setVariantProperties(values, v.id))) setEditing(null);
|
|
2122
2344
|
},
|
|
2123
2345
|
children: [
|
|
2124
|
-
set.options.map((option) => /* @__PURE__ */
|
|
2125
|
-
/* @__PURE__ */
|
|
2126
|
-
/* @__PURE__ */
|
|
2346
|
+
set.options.map((option) => /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2", children: [
|
|
2347
|
+
/* @__PURE__ */ jsx7("span", { className: "w-16 shrink-0 truncate text-muted-foreground", children: option.name }),
|
|
2348
|
+
/* @__PURE__ */ jsx7(
|
|
2127
2349
|
"input",
|
|
2128
2350
|
{
|
|
2129
2351
|
type: "text",
|
|
@@ -2134,9 +2356,9 @@ function CanvasComponentsPanel({
|
|
|
2134
2356
|
}
|
|
2135
2357
|
)
|
|
2136
2358
|
] }, option.name)),
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2139
|
-
/* @__PURE__ */
|
|
2359
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex gap-1", children: [
|
|
2360
|
+
/* @__PURE__ */ jsx7("button", { type: "submit", className: "rounded border border-border px-2 py-0.5 hover:bg-muted", "data-action": "save-variant", children: "Save" }),
|
|
2361
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "rounded px-2 py-0.5 hover:bg-muted", "data-action": "cancel-variant", onClick: () => setEditing(null), children: "Cancel" })
|
|
2140
2362
|
] })
|
|
2141
2363
|
]
|
|
2142
2364
|
}
|
|
@@ -2144,7 +2366,7 @@ function CanvasComponentsPanel({
|
|
|
2144
2366
|
] }, v.id)) })
|
|
2145
2367
|
] }, set.id)),
|
|
2146
2368
|
lone.map((c) => item(c.id, c.name, c.instanceCount, { "data-kind": "component" })),
|
|
2147
|
-
all.length === 0 ? /* @__PURE__ */
|
|
2369
|
+
all.length === 0 ? /* @__PURE__ */ jsx7("p", { className: "text-muted-foreground", children: "No components yet. Select a frame and choose Create Component." }) : null
|
|
2148
2370
|
] });
|
|
2149
2371
|
}
|
|
2150
2372
|
function CanvasInstanceInspector({
|
|
@@ -2163,27 +2385,27 @@ function CanvasInstanceInspector({
|
|
|
2163
2385
|
const allComponents = listCanvasComponents(nodes).components;
|
|
2164
2386
|
const linked = info.status === "linked";
|
|
2165
2387
|
const btn = "rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-40";
|
|
2166
|
-
return /* @__PURE__ */
|
|
2167
|
-
/* @__PURE__ */
|
|
2168
|
-
/* @__PURE__ */
|
|
2169
|
-
info.nested ? /* @__PURE__ */
|
|
2388
|
+
return /* @__PURE__ */ jsxs7("div", { "data-instance-inspector": "", "data-instance-id": info.id, className: `flex flex-col gap-2 text-xs text-foreground ${className}`, children: [
|
|
2389
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2390
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate font-medium", "data-instance-main": "", children: linked ? info.componentName : "Main component missing" }),
|
|
2391
|
+
info.nested ? /* @__PURE__ */ jsx7("span", { className: "text-muted-foreground", children: "Nested" }) : null
|
|
2170
2392
|
] }),
|
|
2171
|
-
info.variantOptions.map((option) => /* @__PURE__ */
|
|
2172
|
-
/* @__PURE__ */
|
|
2173
|
-
/* @__PURE__ */
|
|
2393
|
+
info.variantOptions.map((option) => /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2", "data-variant-property": option.name, children: [
|
|
2394
|
+
/* @__PURE__ */ jsx7("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: option.name }),
|
|
2395
|
+
/* @__PURE__ */ jsx7(
|
|
2174
2396
|
"select",
|
|
2175
2397
|
{
|
|
2176
2398
|
"aria-label": `${option.name} variant`,
|
|
2177
2399
|
className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
|
|
2178
2400
|
value: info.variant[option.name] ?? "",
|
|
2179
2401
|
onChange: (e) => setProp(option.name, e.currentTarget.value),
|
|
2180
|
-
children: option.values.map((v) => /* @__PURE__ */
|
|
2402
|
+
children: option.values.map((v) => /* @__PURE__ */ jsx7("option", { value: v, children: v }, v))
|
|
2181
2403
|
}
|
|
2182
2404
|
)
|
|
2183
2405
|
] }, option.name)),
|
|
2184
|
-
info.properties.map((p) => /* @__PURE__ */
|
|
2185
|
-
/* @__PURE__ */
|
|
2186
|
-
p.type === "boolean" ? /* @__PURE__ */
|
|
2406
|
+
info.properties.map((p) => /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2", "data-component-property": p.name, children: [
|
|
2407
|
+
/* @__PURE__ */ jsx7("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: p.name }),
|
|
2408
|
+
p.type === "boolean" ? /* @__PURE__ */ jsx7("input", { type: "checkbox", "aria-label": p.name, checked: p.value === true, onChange: (e) => setProp(p.name, e.currentTarget.checked) }) : p.type === "text" ? /* @__PURE__ */ jsx7(
|
|
2187
2409
|
"input",
|
|
2188
2410
|
{
|
|
2189
2411
|
type: "text",
|
|
@@ -2198,22 +2420,22 @@ function CanvasInstanceInspector({
|
|
|
2198
2420
|
}
|
|
2199
2421
|
},
|
|
2200
2422
|
String(p.value)
|
|
2201
|
-
) : /* @__PURE__ */
|
|
2423
|
+
) : /* @__PURE__ */ jsx7(
|
|
2202
2424
|
"select",
|
|
2203
2425
|
{
|
|
2204
2426
|
"aria-label": p.name,
|
|
2205
2427
|
className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
|
|
2206
2428
|
value: String(p.value),
|
|
2207
2429
|
onChange: (e) => setProp(p.name, e.currentTarget.value),
|
|
2208
|
-
children: allComponents.filter((c) => !p.preferred?.length || p.preferred.includes(c.id) || c.id === p.value).map((c) => /* @__PURE__ */
|
|
2430
|
+
children: allComponents.filter((c) => !p.preferred?.length || p.preferred.includes(c.id) || c.id === p.value).map((c) => /* @__PURE__ */ jsx7("option", { value: c.id, children: c.name }, c.id))
|
|
2209
2431
|
}
|
|
2210
2432
|
)
|
|
2211
2433
|
] }, p.name)),
|
|
2212
|
-
info.overrides.length ? /* @__PURE__ */
|
|
2213
|
-
/* @__PURE__ */
|
|
2214
|
-
info.overrides.map((o) => /* @__PURE__ */
|
|
2215
|
-
/* @__PURE__ */
|
|
2216
|
-
o.groups.map((g) => /* @__PURE__ */
|
|
2434
|
+
info.overrides.length ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1", "data-instance-overrides": "", children: [
|
|
2435
|
+
/* @__PURE__ */ jsx7("span", { className: "text-muted-foreground", children: "Overrides" }),
|
|
2436
|
+
info.overrides.map((o) => /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-1", "data-override-layer": o.id, children: [
|
|
2437
|
+
/* @__PURE__ */ jsx7("span", { className: "mr-1 truncate", children: o.name }),
|
|
2438
|
+
o.groups.map((g) => /* @__PURE__ */ jsxs7(
|
|
2217
2439
|
"button",
|
|
2218
2440
|
{
|
|
2219
2441
|
type: "button",
|
|
@@ -2230,11 +2452,11 @@ function CanvasInstanceInspector({
|
|
|
2230
2452
|
))
|
|
2231
2453
|
] }, o.id))
|
|
2232
2454
|
] }) : null,
|
|
2233
|
-
/* @__PURE__ */
|
|
2234
|
-
linked ? /* @__PURE__ */
|
|
2235
|
-
/* @__PURE__ */
|
|
2236
|
-
/* @__PURE__ */
|
|
2237
|
-
/* @__PURE__ */
|
|
2455
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-1", children: [
|
|
2456
|
+
linked ? /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
2457
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, "data-action": "reset", onClick: () => report(components.resetOverrides(info.id)), children: "Reset all" }),
|
|
2458
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, "data-action": "go-to-main", onClick: () => components.goToMainComponent(info.id), children: "Go to main" }),
|
|
2459
|
+
/* @__PURE__ */ jsx7(
|
|
2238
2460
|
"button",
|
|
2239
2461
|
{
|
|
2240
2462
|
type: "button",
|
|
@@ -2245,8 +2467,8 @@ function CanvasInstanceInspector({
|
|
|
2245
2467
|
children: "Push changes"
|
|
2246
2468
|
}
|
|
2247
2469
|
)
|
|
2248
|
-
] }) : /* @__PURE__ */
|
|
2249
|
-
/* @__PURE__ */
|
|
2470
|
+
] }) : /* @__PURE__ */ jsx7("button", { type: "button", className: btn, "data-action": "restore", onClick: () => report(components.restoreMainComponent(info.rootId)), children: "Restore main component" }),
|
|
2471
|
+
/* @__PURE__ */ jsx7(
|
|
2250
2472
|
"button",
|
|
2251
2473
|
{
|
|
2252
2474
|
type: "button",
|
|
@@ -2296,7 +2518,19 @@ import {
|
|
|
2296
2518
|
isCanvasComponentSet,
|
|
2297
2519
|
isCanvasInstance,
|
|
2298
2520
|
wouldCreateComponentCycle,
|
|
2299
|
-
CANVAS_COMPONENT_DRAG_TYPE as CANVAS_COMPONENT_DRAG_TYPE2
|
|
2521
|
+
CANVAS_COMPONENT_DRAG_TYPE as CANVAS_COMPONENT_DRAG_TYPE2,
|
|
2522
|
+
createCanvasDrawController as createCanvasDrawController2,
|
|
2523
|
+
createDefaultStrokeStyle,
|
|
2524
|
+
findStrokesAtPoint,
|
|
2525
|
+
streamlinePoints,
|
|
2526
|
+
strokePointsToPathData as strokePointsToPathData2,
|
|
2527
|
+
strokeToShapeNode,
|
|
2528
|
+
CANVAS_GRADIENT_PRESETS,
|
|
2529
|
+
isCanvasGradient,
|
|
2530
|
+
parseCssGradient,
|
|
2531
|
+
resolveCanvasGradient as resolveCanvasGradient2,
|
|
2532
|
+
angleToSvgLinearCoords,
|
|
2533
|
+
gradientToSvgDef as gradientToSvgDef2
|
|
2300
2534
|
} from "@pixerate/editor/canvas";
|
|
2301
2535
|
export {
|
|
2302
2536
|
ANIMATABLE_PROPERTIES,
|
|
@@ -2310,12 +2544,14 @@ export {
|
|
|
2310
2544
|
AnimationPlayer,
|
|
2311
2545
|
AnimationTimeline,
|
|
2312
2546
|
CANVAS_COMPONENT_DRAG_TYPE2 as CANVAS_COMPONENT_DRAG_TYPE,
|
|
2547
|
+
CANVAS_GRADIENT_PRESETS,
|
|
2313
2548
|
CANVAS_TOKEN_PROPERTIES,
|
|
2314
2549
|
CHILD_LAYOUT_DATA_KEY,
|
|
2315
2550
|
CONNECTION_LINE_TYPES,
|
|
2316
2551
|
CSS_ANIMATION_PROPERTIES,
|
|
2317
2552
|
CUBIC_BEZIER_PRESETS,
|
|
2318
2553
|
CanvasComponentsPanel,
|
|
2554
|
+
CanvasDrawLayer,
|
|
2319
2555
|
CanvasGuidesLayer,
|
|
2320
2556
|
CanvasInstanceInspector,
|
|
2321
2557
|
CanvasScenesStore2 as CanvasScenesStore,
|
|
@@ -2335,6 +2571,7 @@ export {
|
|
|
2335
2571
|
addCanvasVariant,
|
|
2336
2572
|
addKeyframesAtTime,
|
|
2337
2573
|
alignNodes,
|
|
2574
|
+
angleToSvgLinearCoords,
|
|
2338
2575
|
animateNode,
|
|
2339
2576
|
applyAnimation,
|
|
2340
2577
|
applyAnimationOverrides,
|
|
@@ -2375,8 +2612,10 @@ export {
|
|
|
2375
2612
|
createCanvasAutoLayoutController2 as createCanvasAutoLayoutController,
|
|
2376
2613
|
createCanvasComponent,
|
|
2377
2614
|
createCanvasComponentsController2 as createCanvasComponentsController,
|
|
2615
|
+
createCanvasDrawController2 as createCanvasDrawController,
|
|
2378
2616
|
createCanvasInstance,
|
|
2379
2617
|
createCanvasScenesStore,
|
|
2618
|
+
createDefaultStrokeStyle,
|
|
2380
2619
|
createFanOutTrajectory2 as createFanOutTrajectory,
|
|
2381
2620
|
createGuideIndex,
|
|
2382
2621
|
createNodeGuideIndex,
|
|
@@ -2404,6 +2643,7 @@ export {
|
|
|
2404
2643
|
excludePaths,
|
|
2405
2644
|
exportCssAnimation,
|
|
2406
2645
|
findConnectorSnap,
|
|
2646
|
+
findStrokesAtPoint,
|
|
2407
2647
|
fitCubicRun,
|
|
2408
2648
|
fitCubics,
|
|
2409
2649
|
fitFreehandPath,
|
|
@@ -2453,6 +2693,7 @@ export {
|
|
|
2453
2693
|
getTimelineTicks2 as getTimelineTicks,
|
|
2454
2694
|
getTokenPropertyScope,
|
|
2455
2695
|
getTokensForProperty2 as getTokensForProperty,
|
|
2696
|
+
gradientToSvgDef2 as gradientToSvgDef,
|
|
2456
2697
|
handlePoint,
|
|
2457
2698
|
hasVisibleStroke,
|
|
2458
2699
|
inferResizeHandle,
|
|
@@ -2467,6 +2708,7 @@ export {
|
|
|
2467
2708
|
isAutoLayoutFrame,
|
|
2468
2709
|
isCanvasComponent,
|
|
2469
2710
|
isCanvasComponentSet,
|
|
2711
|
+
isCanvasGradient,
|
|
2470
2712
|
isCanvasInstance,
|
|
2471
2713
|
isCssExportExact,
|
|
2472
2714
|
isEventFromTextInput3 as isEventFromTextInput,
|
|
@@ -2514,6 +2756,7 @@ export {
|
|
|
2514
2756
|
parseCanvasClipboardData2 as parseCanvasClipboardData,
|
|
2515
2757
|
parseCanvasScenes,
|
|
2516
2758
|
parseCssEasing,
|
|
2759
|
+
parseCssGradient,
|
|
2517
2760
|
parseKeyframeClipboard,
|
|
2518
2761
|
parseOklab,
|
|
2519
2762
|
parseSvgPath,
|
|
@@ -2545,6 +2788,7 @@ export {
|
|
|
2545
2788
|
repositionNodesTo,
|
|
2546
2789
|
resetCanvasInstanceOverrides,
|
|
2547
2790
|
resizeHandleAxes,
|
|
2791
|
+
resolveCanvasGradient2 as resolveCanvasGradient,
|
|
2548
2792
|
resolveCanvasTokens2 as resolveCanvasTokens,
|
|
2549
2793
|
resolveEasing,
|
|
2550
2794
|
resolvePadding,
|
|
@@ -2577,7 +2821,10 @@ export {
|
|
|
2577
2821
|
snapTimeToFrame,
|
|
2578
2822
|
snapToGrid,
|
|
2579
2823
|
springAt,
|
|
2824
|
+
streamlinePoints,
|
|
2580
2825
|
strokeOutlineRings,
|
|
2826
|
+
strokePointsToPathData2 as strokePointsToPathData,
|
|
2827
|
+
strokeToShapeNode,
|
|
2581
2828
|
subtractPaths,
|
|
2582
2829
|
subtractPolygons,
|
|
2583
2830
|
swapCanvasInstance,
|
|
@@ -2600,6 +2847,7 @@ export {
|
|
|
2600
2847
|
useCanvasClipboard,
|
|
2601
2848
|
useCanvasComponents,
|
|
2602
2849
|
useCanvasDocking,
|
|
2850
|
+
useCanvasDraw,
|
|
2603
2851
|
useCanvasExplosion,
|
|
2604
2852
|
useCanvasGraph,
|
|
2605
2853
|
useCanvasLayout,
|