@hunterchen/canvas 0.7.0 → 0.9.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.
Files changed (60) hide show
  1. package/README.md +196 -8
  2. package/dist/components/canvas/backgrounds.d.ts +4 -4
  3. package/dist/components/canvas/backgrounds.d.ts.map +1 -1
  4. package/dist/components/canvas/backgrounds.js +68 -39
  5. package/dist/components/canvas/backgrounds.js.map +1 -1
  6. package/dist/components/canvas/canvas.d.ts +3 -1
  7. package/dist/components/canvas/canvas.d.ts.map +1 -1
  8. package/dist/components/canvas/canvas.js +451 -387
  9. package/dist/components/canvas/canvas.js.map +1 -1
  10. package/dist/components/canvas/component.js +108 -174
  11. package/dist/components/canvas/component.js.map +1 -1
  12. package/dist/components/canvas/draggable.js +168 -151
  13. package/dist/components/canvas/draggable.js.map +1 -1
  14. package/dist/components/canvas/navbar/index.d.ts +4 -2
  15. package/dist/components/canvas/navbar/index.d.ts.map +1 -1
  16. package/dist/components/canvas/navbar/index.js +168 -101
  17. package/dist/components/canvas/navbar/index.js.map +1 -1
  18. package/dist/components/canvas/navbar/single-button.d.ts +10 -1
  19. package/dist/components/canvas/navbar/single-button.d.ts.map +1 -1
  20. package/dist/components/canvas/navbar/single-button.js +176 -69
  21. package/dist/components/canvas/navbar/single-button.js.map +1 -1
  22. package/dist/components/canvas/toolbar.js +121 -82
  23. package/dist/components/canvas/toolbar.js.map +1 -1
  24. package/dist/components/canvas/wrapper.js +127 -99
  25. package/dist/components/canvas/wrapper.js.map +1 -1
  26. package/dist/contexts/CanvasContext.js +25 -17
  27. package/dist/contexts/CanvasContext.js.map +1 -1
  28. package/dist/contexts/PerformanceContext.js +51 -50
  29. package/dist/contexts/PerformanceContext.js.map +1 -1
  30. package/dist/hooks/usePerformanceMode.js +36 -37
  31. package/dist/hooks/usePerformanceMode.js.map +1 -1
  32. package/dist/hooks/useWindowDimensions.js +22 -18
  33. package/dist/hooks/useWindowDimensions.js.map +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +17 -21
  37. package/dist/lib/canvas.js +65 -72
  38. package/dist/lib/canvas.js.map +1 -1
  39. package/dist/lib/constants.js +78 -92
  40. package/dist/lib/constants.js.map +1 -1
  41. package/dist/lib/utils.js +10 -5
  42. package/dist/lib/utils.js.map +1 -1
  43. package/dist/styles.css +1 -1
  44. package/dist/types/index.d.ts +69 -0
  45. package/dist/types/index.d.ts.map +1 -1
  46. package/dist/utils/performance.js +18 -23
  47. package/dist/utils/performance.js.map +1 -1
  48. package/package.json +7 -21
  49. package/src/components/canvas/backgrounds.tsx +7 -7
  50. package/src/components/canvas/canvas.tsx +9 -2
  51. package/src/components/canvas/navbar/index.tsx +91 -15
  52. package/src/components/canvas/navbar/single-button.tsx +210 -56
  53. package/src/index.ts +5 -0
  54. package/src/styles.css +15 -13
  55. package/src/types/index.ts +91 -0
  56. package/dist/components/canvas/offest.js +0 -12
  57. package/dist/components/canvas/offest.js.map +0 -1
  58. package/dist/index.js.map +0 -1
  59. package/dist/types/index.js +0 -6
  60. package/dist/types/index.js.map +0 -1
@@ -1,86 +1,125 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useTransform, motion } from "framer-motion";
3
- import { useEffect, useState, useMemo } from "react";
4
- import { useCanvasContext } from "../../contexts/CanvasContext";
5
- import { TOOLBAR_OPACITY_POS_EPS, TOOLBAR_OPACITY_SCALE_EPS, } from "../../lib/constants";
6
- import { cn } from "../../lib/utils";
1
+ import { useCanvasContext } from "../../contexts/CanvasContext.js";
2
+ import { TOOLBAR_OPACITY_POS_EPS, TOOLBAR_OPACITY_SCALE_EPS } from "../../lib/constants.js";
3
+ import { cn } from "../../lib/utils.js";
4
+ import { motion, useTransform } from "framer-motion";
5
+ import { useEffect, useMemo, useState } from "react";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/components/canvas/toolbar.tsx
7
9
  const positionStyles = {
8
- "top-left": "left-4 top-6 sm:top-4",
9
- "top-right": "right-4 top-6 sm:top-4",
10
- "bottom-left": "left-4 bottom-6 sm:bottom-4",
11
- "bottom-right": "right-4 bottom-6 sm:bottom-4",
10
+ "top-left": "left-4 top-6 sm:top-4",
11
+ "top-right": "right-4 top-6 sm:top-4",
12
+ "bottom-left": "left-4 bottom-6 sm:bottom-4",
13
+ "bottom-right": "right-4 bottom-6 sm:bottom-4"
12
14
  };
13
- const Toolbar = ({ homeCoordinates = { x: 0, y: 0 }, config = {}, }) => {
14
- const { x, y, scale } = useCanvasContext();
15
- const [hasMounted, setHasMounted] = useState(false);
16
- const { display = "both", position = "top-left", disableAutoHide = false, className, coordinatesClassName, scaleClassName, separatorClassName, style, coordinatesStyle, scaleStyle, separator = "|", separatorGap, coordinatesFormat, scaleFormat, } = config;
17
- const separatorStyle = separatorGap
18
- ? {
19
- marginInline: typeof separatorGap === "number" ? `${separatorGap}px` : separatorGap,
20
- }
21
- : undefined;
22
- useEffect(() => {
23
- setHasMounted(true);
24
- }, []);
25
- // numeric MotionValues
26
- const rawDx = useTransform([x, scale], ([lx, ls]) => -(lx / ls) + homeCoordinates.x);
27
- const rawDy = useTransform([y, scale], ([ly, ls]) => -(ly / ls) + homeCoordinates.y);
28
- // formatted MotionValues for default display
29
- const displayX = useTransform(rawDx, (v) => Math.round(v).toString());
30
- const displayY = useTransform(rawDy, (v) => Math.round(v).toString());
31
- const displayScale = useTransform(scale, (v) => v.toFixed(2));
32
- // For custom formatters, we need to use state to track values
33
- const [currentX, setCurrentX] = useState(0);
34
- const [currentY, setCurrentY] = useState(0);
35
- const [currentScale, setCurrentScale] = useState(1);
36
- useEffect(() => {
37
- const unsubX = rawDx.on("change", (v) => setCurrentX(Math.round(v)));
38
- const unsubY = rawDy.on("change", (v) => setCurrentY(Math.round(v)));
39
- const unsubScale = scale.on("change", (v) => setCurrentScale(v));
40
- return () => {
41
- unsubX();
42
- unsubY();
43
- unsubScale();
44
- };
45
- }, [rawDx, rawDy, scale]);
46
- const opacity = useTransform([rawDx, rawDy, scale], ([dx, dy, ls]) => {
47
- if (disableAutoHide)
48
- return 1;
49
- return Math.abs(dx) < TOOLBAR_OPACITY_POS_EPS &&
50
- Math.abs(dy) < TOOLBAR_OPACITY_POS_EPS &&
51
- Math.abs(ls - 1) < TOOLBAR_OPACITY_SCALE_EPS
52
- ? 0
53
- : 1;
54
- });
55
- const handlePointerDown = (e) => e.stopPropagation();
56
- const showCoordinates = display === "coordinates" || display === "both";
57
- const showScale = display === "scale" || display === "both";
58
- const showSeparator = display === "both";
59
- // Compute formatted values
60
- const formattedCoordinates = useMemo(() => {
61
- if (coordinatesFormat) {
62
- return coordinatesFormat(currentX, currentY);
63
- }
64
- return null; // Will use motion spans for default
65
- }, [coordinatesFormat, currentX, currentY]);
66
- const formattedScale = useMemo(() => {
67
- if (scaleFormat) {
68
- return scaleFormat(currentScale);
69
- }
70
- return null; // Will use motion span for default
71
- }, [scaleFormat, currentScale]);
72
- // Placeholder content for SSR/initial render
73
- const placeholderContent = useMemo(() => {
74
- const parts = [];
75
- if (showCoordinates)
76
- parts.push("(0, 0)");
77
- if (showSeparator)
78
- parts.push(separator);
79
- if (showScale)
80
- parts.push("1.00x");
81
- return parts.join("");
82
- }, [showCoordinates, showScale, showSeparator, separator]);
83
- return (_jsx(motion.div, { className: cn("absolute z-[1000] cursor-default select-none rounded-[10px] border border-border bg-canvas-offwhite p-2 font-mono text-xs text-canvas-heavy shadow-[0_6px_12px_rgba(0,0,0,0.10)] md:text-sm", positionStyles[position], className), onPointerDown: handlePointerDown, "data-toolbar-button": true, style: { opacity, ...style }, children: hasMounted ? (_jsxs(_Fragment, { children: [showCoordinates && (_jsx("span", { className: coordinatesClassName, style: coordinatesStyle, children: formattedCoordinates !== null ? (formattedCoordinates) : (_jsxs(_Fragment, { children: ["(", _jsx(motion.span, { children: displayX }), ",", " ", _jsx(motion.span, { children: displayY }), ")"] })) })), showSeparator && (_jsx("span", { className: cn("text-canvas-light", separatorClassName), style: separatorStyle, children: separator })), showScale && (_jsx("span", { className: scaleClassName, style: scaleStyle, children: formattedScale !== null ? (formattedScale) : (_jsxs(_Fragment, { children: [_jsx(motion.span, { children: displayScale }), "x"] })) }))] })) : (_jsx("span", { style: { opacity: 0 }, children: placeholderContent })) }));
15
+ const Toolbar = ({ homeCoordinates = {
16
+ x: 0,
17
+ y: 0
18
+ }, config = {} }) => {
19
+ const { x, y, scale } = useCanvasContext();
20
+ const [hasMounted, setHasMounted] = useState(false);
21
+ const { display = "both", position = "top-left", disableAutoHide = false, className, coordinatesClassName, scaleClassName, separatorClassName, style, coordinatesStyle, scaleStyle, separator = "|", separatorGap, coordinatesFormat, scaleFormat } = config;
22
+ const separatorStyle = separatorGap ? { marginInline: typeof separatorGap === "number" ? `${separatorGap}px` : separatorGap } : void 0;
23
+ useEffect(() => {
24
+ setHasMounted(true);
25
+ }, []);
26
+ const rawDx = useTransform([x, scale], ([lx, ls]) => -(lx / ls) + homeCoordinates.x);
27
+ const rawDy = useTransform([y, scale], ([ly, ls]) => -(ly / ls) + homeCoordinates.y);
28
+ const displayX = useTransform(rawDx, (v) => Math.round(v).toString());
29
+ const displayY = useTransform(rawDy, (v) => Math.round(v).toString());
30
+ const displayScale = useTransform(scale, (v) => v.toFixed(2));
31
+ const [currentX, setCurrentX] = useState(0);
32
+ const [currentY, setCurrentY] = useState(0);
33
+ const [currentScale, setCurrentScale] = useState(1);
34
+ useEffect(() => {
35
+ const unsubX = rawDx.on("change", (v) => setCurrentX(Math.round(v)));
36
+ const unsubY = rawDy.on("change", (v) => setCurrentY(Math.round(v)));
37
+ const unsubScale = scale.on("change", (v) => setCurrentScale(v));
38
+ return () => {
39
+ unsubX();
40
+ unsubY();
41
+ unsubScale();
42
+ };
43
+ }, [
44
+ rawDx,
45
+ rawDy,
46
+ scale
47
+ ]);
48
+ const opacity = useTransform([
49
+ rawDx,
50
+ rawDy,
51
+ scale
52
+ ], ([dx, dy, ls]) => {
53
+ if (disableAutoHide) return 1;
54
+ return Math.abs(dx) < TOOLBAR_OPACITY_POS_EPS && Math.abs(dy) < TOOLBAR_OPACITY_POS_EPS && Math.abs(ls - 1) < TOOLBAR_OPACITY_SCALE_EPS ? 0 : 1;
55
+ });
56
+ const handlePointerDown = (e) => e.stopPropagation();
57
+ const showCoordinates = display === "coordinates" || display === "both";
58
+ const showScale = display === "scale" || display === "both";
59
+ const showSeparator = display === "both";
60
+ const formattedCoordinates = useMemo(() => {
61
+ if (coordinatesFormat) return coordinatesFormat(currentX, currentY);
62
+ return null;
63
+ }, [
64
+ coordinatesFormat,
65
+ currentX,
66
+ currentY
67
+ ]);
68
+ const formattedScale = useMemo(() => {
69
+ if (scaleFormat) return scaleFormat(currentScale);
70
+ return null;
71
+ }, [scaleFormat, currentScale]);
72
+ const placeholderContent = useMemo(() => {
73
+ const parts = [];
74
+ if (showCoordinates) parts.push("(0, 0)");
75
+ if (showSeparator) parts.push(separator);
76
+ if (showScale) parts.push("1.00x");
77
+ return parts.join("");
78
+ }, [
79
+ showCoordinates,
80
+ showScale,
81
+ showSeparator,
82
+ separator
83
+ ]);
84
+ return /* @__PURE__ */ jsx(motion.div, {
85
+ className: cn("absolute z-[1000] cursor-default select-none rounded-[10px] border border-border bg-canvas-offwhite p-2 font-mono text-xs text-canvas-heavy shadow-[0_6px_12px_rgba(0,0,0,0.10)] md:text-sm", positionStyles[position], className),
86
+ onPointerDown: handlePointerDown,
87
+ "data-toolbar-button": true,
88
+ style: {
89
+ opacity,
90
+ ...style
91
+ },
92
+ children: hasMounted ? /* @__PURE__ */ jsxs(Fragment, { children: [
93
+ showCoordinates && /* @__PURE__ */ jsx("span", {
94
+ className: coordinatesClassName,
95
+ style: coordinatesStyle,
96
+ children: formattedCoordinates !== null ? formattedCoordinates : /* @__PURE__ */ jsxs(Fragment, { children: [
97
+ "(",
98
+ /* @__PURE__ */ jsx(motion.span, { children: displayX }),
99
+ ",",
100
+ " ",
101
+ /* @__PURE__ */ jsx(motion.span, { children: displayY }),
102
+ ")"
103
+ ] })
104
+ }),
105
+ showSeparator && /* @__PURE__ */ jsx("span", {
106
+ className: cn("text-canvas-light", separatorClassName),
107
+ style: separatorStyle,
108
+ children: separator
109
+ }),
110
+ showScale && /* @__PURE__ */ jsx("span", {
111
+ className: scaleClassName,
112
+ style: scaleStyle,
113
+ children: formattedScale !== null ? formattedScale : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(motion.span, { children: displayScale }), "x"] })
114
+ })
115
+ ] }) : /* @__PURE__ */ jsx("span", {
116
+ style: { opacity: 0 },
117
+ children: placeholderContent
118
+ })
119
+ });
84
120
  };
85
- export default Toolbar;
121
+ var toolbar_default = Toolbar;
122
+
123
+ //#endregion
124
+ export { toolbar_default as default };
86
125
  //# sourceMappingURL=toolbar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../../src/components/canvas/toolbar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"toolbar.js","names":[],"sources":["../../../src/components/canvas/toolbar.tsx"],"sourcesContent":["import { type Point, useTransform, motion } from \"framer-motion\";\nimport { useEffect, useState, useMemo } from \"react\";\nimport { useCanvasContext } from \"../../contexts/CanvasContext\";\nimport {\n TOOLBAR_OPACITY_POS_EPS,\n TOOLBAR_OPACITY_SCALE_EPS,\n} from \"../../lib/constants\";\nimport { cn } from \"../../lib/utils\";\nimport type { ToolbarConfig, ToolbarPosition } from \"../../types\";\n\ntype ToolbarProps = {\n homeCoordinates?: Point;\n config?: ToolbarConfig;\n};\n\nconst positionStyles: Record<ToolbarPosition, string> = {\n \"top-left\": \"left-4 top-6 sm:top-4\",\n \"top-right\": \"right-4 top-6 sm:top-4\",\n \"bottom-left\": \"left-4 bottom-6 sm:bottom-4\",\n \"bottom-right\": \"right-4 bottom-6 sm:bottom-4\",\n};\n\nconst Toolbar = ({\n homeCoordinates = { x: 0, y: 0 },\n config = {},\n}: ToolbarProps) => {\n const { x, y, scale } = useCanvasContext();\n const [hasMounted, setHasMounted] = useState(false);\n\n const {\n display = \"both\",\n position = \"top-left\",\n disableAutoHide = false,\n className,\n coordinatesClassName,\n scaleClassName,\n separatorClassName,\n style,\n coordinatesStyle,\n scaleStyle,\n separator = \"|\",\n separatorGap,\n coordinatesFormat,\n scaleFormat,\n } = config;\n\n const separatorStyle: React.CSSProperties | undefined = separatorGap\n ? {\n marginInline:\n typeof separatorGap === \"number\" ? `${separatorGap}px` : separatorGap,\n }\n : undefined;\n\n useEffect(() => {\n setHasMounted(true);\n }, []);\n\n // numeric MotionValues\n const rawDx = useTransform(\n [x, scale],\n ([lx, ls]) => -((lx as number) / (ls as number)) + homeCoordinates.x\n );\n const rawDy = useTransform(\n [y, scale],\n ([ly, ls]) => -((ly as number) / (ls as number)) + homeCoordinates.y\n );\n\n // formatted MotionValues for default display\n const displayX = useTransform(rawDx, (v) => Math.round(v).toString());\n const displayY = useTransform(rawDy, (v) => Math.round(v).toString());\n const displayScale = useTransform(scale, (v) => v.toFixed(2));\n\n // For custom formatters, we need to use state to track values\n const [currentX, setCurrentX] = useState(0);\n const [currentY, setCurrentY] = useState(0);\n const [currentScale, setCurrentScale] = useState(1);\n\n useEffect(() => {\n const unsubX = rawDx.on(\"change\", (v) => setCurrentX(Math.round(v)));\n const unsubY = rawDy.on(\"change\", (v) => setCurrentY(Math.round(v)));\n const unsubScale = scale.on(\"change\", (v) => setCurrentScale(v));\n return () => {\n unsubX();\n unsubY();\n unsubScale();\n };\n }, [rawDx, rawDy, scale]);\n\n const opacity = useTransform([rawDx, rawDy, scale], ([dx, dy, ls]) => {\n if (disableAutoHide) return 1;\n return Math.abs(dx as number) < TOOLBAR_OPACITY_POS_EPS &&\n Math.abs(dy as number) < TOOLBAR_OPACITY_POS_EPS &&\n Math.abs((ls as number) - 1) < TOOLBAR_OPACITY_SCALE_EPS\n ? 0\n : 1;\n });\n\n const handlePointerDown = (e: React.PointerEvent) => e.stopPropagation();\n\n const showCoordinates = display === \"coordinates\" || display === \"both\";\n const showScale = display === \"scale\" || display === \"both\";\n const showSeparator = display === \"both\";\n\n // Compute formatted values\n const formattedCoordinates = useMemo(() => {\n if (coordinatesFormat) {\n return coordinatesFormat(currentX, currentY);\n }\n return null; // Will use motion spans for default\n }, [coordinatesFormat, currentX, currentY]);\n\n const formattedScale = useMemo(() => {\n if (scaleFormat) {\n return scaleFormat(currentScale);\n }\n return null; // Will use motion span for default\n }, [scaleFormat, currentScale]);\n\n // Placeholder content for SSR/initial render\n const placeholderContent = useMemo(() => {\n const parts: string[] = [];\n if (showCoordinates) parts.push(\"(0, 0)\");\n if (showSeparator) parts.push(separator);\n if (showScale) parts.push(\"1.00x\");\n return parts.join(\"\");\n }, [showCoordinates, showScale, showSeparator, separator]);\n\n return (\n <motion.div\n className={cn(\n \"absolute z-[1000] cursor-default select-none rounded-[10px] border border-border bg-canvas-offwhite p-2 font-mono text-xs text-canvas-heavy shadow-[0_6px_12px_rgba(0,0,0,0.10)] md:text-sm\",\n positionStyles[position],\n className\n )}\n onPointerDown={handlePointerDown}\n data-toolbar-button\n style={{ opacity, ...style }}\n >\n {hasMounted ? (\n <>\n {showCoordinates && (\n <span className={coordinatesClassName} style={coordinatesStyle}>\n {formattedCoordinates !== null ? (\n formattedCoordinates\n ) : (\n <>\n (<motion.span>{displayX}</motion.span>,{\" \"}\n <motion.span>{displayY}</motion.span>)\n </>\n )}\n </span>\n )}\n {showSeparator && (\n <span\n className={cn(\"text-canvas-light\", separatorClassName)}\n style={separatorStyle}\n >\n {separator}\n </span>\n )}\n {showScale && (\n <span className={scaleClassName} style={scaleStyle}>\n {formattedScale !== null ? (\n formattedScale\n ) : (\n <>\n <motion.span>{displayScale}</motion.span>x\n </>\n )}\n </span>\n )}\n </>\n ) : (\n <span style={{ opacity: 0 }}>{placeholderContent}</span>\n )}\n </motion.div>\n );\n};\n\nexport default Toolbar;\n"],"mappings":"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"}
@@ -1,102 +1,130 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { BLUR_TRANSITION, GROW_TRANSITION, INTRO_ASPECT_RATIO, MAX_DIM_RATIO } from "../../lib/constants.js";
2
2
  import { motion } from "framer-motion";
3
- import { useState, useEffect, useRef } from "react";
4
- import { MAX_DIM_RATIO, GROW_TRANSITION, BLUR_TRANSITION, INTRO_ASPECT_RATIO, } from "../../lib/constants";
5
- // Re-export for backward compatibility
6
- export { GROW_TRANSITION as growTransition } from "../../lib/constants";
7
- export const CanvasWrapper = ({ children, introProgress, onIntroGrowComplete, skipIntro = false, introContent, loadingText = "LOADING CANVAS", introBackgroundGradient = "linear-gradient(to top, #d4d4d4 0%, #e5e5e5 50%, #f5f5f5 100%)", wrapperBackground, canvasBoxGradient = "radial-gradient(130.38% 95% at 50.03% 97.25%, #d4d4d4 0%, #e5e5e5 48.09%, #f5f5f5 100%)", growTransition = GROW_TRANSITION, blurTransition = BLUR_TRANSITION, }) => {
8
- const [dimensions, setDimensions] = useState(null);
9
- const [dots, setDots] = useState("..");
10
- const [stage1NotFinished, setStage1NotFinished] = useState(true);
11
- const completedRef = useRef(false);
12
- // If skipIntro is true, immediately complete the intro
13
- useEffect(() => {
14
- if (skipIntro && !completedRef.current) {
15
- completedRef.current = true;
16
- introProgress.set(1);
17
- onIntroGrowComplete?.();
18
- }
19
- }, [skipIntro, introProgress, onIntroGrowComplete]);
20
- // add up to 4 dots, then go back down to 2
21
- useEffect(() => {
22
- if (skipIntro)
23
- return; // Don't animate dots if skipping intro
24
- const interval = setInterval(() => {
25
- setDots((prevDots) => {
26
- if (prevDots.length < 3) {
27
- return prevDots + ".";
28
- }
29
- else {
30
- return ".";
31
- }
32
- });
33
- }, 500);
34
- return () => clearInterval(interval);
35
- }, [skipIntro]);
36
- useEffect(() => {
37
- if (skipIntro)
38
- return; // Don't calculate dimensions if skipping intro
39
- // calculate the initial 3:2 box size with margins (client-only)
40
- const calculateInitialSize = () => {
41
- const vw = window.innerWidth;
42
- const vh = window.innerHeight;
43
- const maxWidth = vw * MAX_DIM_RATIO.width;
44
- const maxHeight = vh * MAX_DIM_RATIO.height;
45
- // width or height as limiter
46
- if (maxWidth / INTRO_ASPECT_RATIO <= maxHeight) {
47
- return { width: maxWidth, height: maxWidth / INTRO_ASPECT_RATIO };
48
- }
49
- else {
50
- return { height: maxHeight, width: maxHeight * INTRO_ASPECT_RATIO };
51
- }
52
- };
53
- setDimensions(calculateInitialSize());
54
- }, [skipIntro]);
55
- // If skipIntro, render children directly without animation wrapper
56
- if (skipIntro) {
57
- return (_jsx(motion.div, { className: "fixed inset-0 overflow-hidden", style: {
58
- touchAction: "none",
59
- userSelect: "none",
60
- pointerEvents: "none",
61
- }, onContextMenu: (e) => e.preventDefault(), children: children }));
62
- }
63
- return (_jsxs(motion.div, { className: "fixed inset-0 overflow-hidden", style: {
64
- // Only use gradient style if no custom wrapperBackground is provided
65
- backgroundImage: stage1NotFinished && !wrapperBackground ? introBackgroundGradient : undefined,
66
- touchAction: "none",
67
- userSelect: "none",
68
- pointerEvents: "none",
69
- }, onContextMenu: (e) => e.preventDefault(), children: [stage1NotFinished && wrapperBackground, stage1NotFinished && (_jsx(_Fragment, { children: introContent })), dimensions && (_jsxs(_Fragment, { children: [_jsx(motion.div, { initial: {
70
- width: dimensions.width,
71
- height: dimensions.height,
72
- opacity: 1,
73
- backgroundImage: canvasBoxGradient,
74
- }, animate: {
75
- opacity: 0,
76
- display: "none",
77
- }, transition: blurTransition, className: "absolute left-1/2 top-1/2 z-20 origin-center -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg" }), _jsx(motion.div, { initial: {
78
- width: dimensions.width,
79
- height: dimensions.height,
80
- }, animate: {
81
- width: "100vw",
82
- height: "100vh",
83
- }, transition: growTransition, onUpdate: (latest) => {
84
- if (completedRef.current)
85
- return;
86
- if (typeof latest.width === "number") {
87
- const w0 = dimensions.width;
88
- const w1 = window.innerWidth;
89
- const progress = w1 === w0 ? 1 : (latest.width - w0) / (w1 - w0);
90
- const clamped = Math.min(Math.max(progress, 0), 1);
91
- introProgress.set(clamped);
92
- }
93
- }, onAnimationComplete: () => {
94
- if (!completedRef.current) {
95
- completedRef.current = true;
96
- introProgress.set(1);
97
- setStage1NotFinished(false);
98
- onIntroGrowComplete?.();
99
- }
100
- }, className: "absolute left-1/2 top-1/2 z-10 origin-center -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg shadow-[0_20px_40px_rgba(103,86,86,0.15)]", children: _jsx("div", { className: "h-full w-full", children: children }) })] })), stage1NotFinished && loadingText && (_jsxs("div", { className: "absolute bottom-24 left-1/2 -translate-x-1/2 text-center font-mono font-semibold text-neutral-500", children: [loadingText, dots] }))] }));
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+
6
+ //#region src/components/canvas/wrapper.tsx
7
+ const CanvasWrapper = ({ children, introProgress, onIntroGrowComplete, skipIntro = false, introContent, loadingText = "LOADING CANVAS", introBackgroundGradient = "linear-gradient(to top, #d4d4d4 0%, #e5e5e5 50%, #f5f5f5 100%)", wrapperBackground, canvasBoxGradient = "radial-gradient(130.38% 95% at 50.03% 97.25%, #d4d4d4 0%, #e5e5e5 48.09%, #f5f5f5 100%)", growTransition = GROW_TRANSITION, blurTransition = BLUR_TRANSITION }) => {
8
+ const [dimensions, setDimensions] = useState(null);
9
+ const [dots, setDots] = useState("..");
10
+ const [stage1NotFinished, setStage1NotFinished] = useState(true);
11
+ const completedRef = useRef(false);
12
+ useEffect(() => {
13
+ if (skipIntro && !completedRef.current) {
14
+ completedRef.current = true;
15
+ introProgress.set(1);
16
+ onIntroGrowComplete?.();
17
+ }
18
+ }, [
19
+ skipIntro,
20
+ introProgress,
21
+ onIntroGrowComplete
22
+ ]);
23
+ useEffect(() => {
24
+ if (skipIntro) return;
25
+ const interval = setInterval(() => {
26
+ setDots((prevDots) => {
27
+ if (prevDots.length < 3) return prevDots + ".";
28
+ else return ".";
29
+ });
30
+ }, 500);
31
+ return () => clearInterval(interval);
32
+ }, [skipIntro]);
33
+ useEffect(() => {
34
+ if (skipIntro) return;
35
+ const calculateInitialSize = () => {
36
+ const vw = window.innerWidth;
37
+ const vh = window.innerHeight;
38
+ const maxWidth = vw * MAX_DIM_RATIO.width;
39
+ const maxHeight = vh * MAX_DIM_RATIO.height;
40
+ if (maxWidth / INTRO_ASPECT_RATIO <= maxHeight) return {
41
+ width: maxWidth,
42
+ height: maxWidth / INTRO_ASPECT_RATIO
43
+ };
44
+ else return {
45
+ height: maxHeight,
46
+ width: maxHeight * INTRO_ASPECT_RATIO
47
+ };
48
+ };
49
+ setDimensions(calculateInitialSize());
50
+ }, [skipIntro]);
51
+ if (skipIntro) return /* @__PURE__ */ jsx(motion.div, {
52
+ className: "fixed inset-0 overflow-hidden",
53
+ style: {
54
+ touchAction: "none",
55
+ userSelect: "none",
56
+ pointerEvents: "none"
57
+ },
58
+ onContextMenu: (e) => e.preventDefault(),
59
+ children
60
+ });
61
+ return /* @__PURE__ */ jsxs(motion.div, {
62
+ className: "fixed inset-0 overflow-hidden",
63
+ style: {
64
+ backgroundImage: stage1NotFinished && !wrapperBackground ? introBackgroundGradient : void 0,
65
+ touchAction: "none",
66
+ userSelect: "none",
67
+ pointerEvents: "none"
68
+ },
69
+ onContextMenu: (e) => e.preventDefault(),
70
+ children: [
71
+ stage1NotFinished && wrapperBackground,
72
+ stage1NotFinished && /* @__PURE__ */ jsx(Fragment, { children: introContent }),
73
+ dimensions && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(motion.div, {
74
+ initial: {
75
+ width: dimensions.width,
76
+ height: dimensions.height,
77
+ opacity: 1,
78
+ backgroundImage: canvasBoxGradient
79
+ },
80
+ animate: {
81
+ opacity: 0,
82
+ display: "none"
83
+ },
84
+ transition: blurTransition,
85
+ className: "absolute left-1/2 top-1/2 z-20 origin-center -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg"
86
+ }), /* @__PURE__ */ jsx(motion.div, {
87
+ initial: {
88
+ width: dimensions.width,
89
+ height: dimensions.height
90
+ },
91
+ animate: {
92
+ width: "100vw",
93
+ height: "100vh"
94
+ },
95
+ transition: growTransition,
96
+ onUpdate: (latest) => {
97
+ if (completedRef.current) return;
98
+ if (typeof latest.width === "number") {
99
+ const w0 = dimensions.width;
100
+ const w1 = window.innerWidth;
101
+ const progress = w1 === w0 ? 1 : (latest.width - w0) / (w1 - w0);
102
+ const clamped = Math.min(Math.max(progress, 0), 1);
103
+ introProgress.set(clamped);
104
+ }
105
+ },
106
+ onAnimationComplete: () => {
107
+ if (!completedRef.current) {
108
+ completedRef.current = true;
109
+ introProgress.set(1);
110
+ setStage1NotFinished(false);
111
+ onIntroGrowComplete?.();
112
+ }
113
+ },
114
+ className: "absolute left-1/2 top-1/2 z-10 origin-center -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg shadow-[0_20px_40px_rgba(103,86,86,0.15)]",
115
+ children: /* @__PURE__ */ jsx("div", {
116
+ className: "h-full w-full",
117
+ children
118
+ })
119
+ })] }),
120
+ stage1NotFinished && loadingText && /* @__PURE__ */ jsxs("div", {
121
+ className: "absolute bottom-24 left-1/2 -translate-x-1/2 text-center font-mono font-semibold text-neutral-500",
122
+ children: [loadingText, dots]
123
+ })
124
+ ]
125
+ });
101
126
  };
127
+
128
+ //#endregion
129
+ export { CanvasWrapper };
102
130
  //# sourceMappingURL=wrapper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../../src/components/canvas/wrapper.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrapper.js","names":[],"sources":["../../../src/components/canvas/wrapper.tsx"],"sourcesContent":["import { motion, type MotionValue, type Transition, useMotionValue } from \"framer-motion\";\nimport { useState, useEffect, useRef, type ReactNode } from \"react\";\nimport {\n MAX_DIM_RATIO,\n GROW_TRANSITION,\n BLUR_TRANSITION,\n INTRO_ASPECT_RATIO,\n} from \"../../lib/constants\";\n\n// Re-export for backward compatibility\nexport { GROW_TRANSITION as growTransition } from \"../../lib/constants\";\n\ninterface CanvasWrapperProps {\n children: React.ReactNode;\n /** Shared progress MV (0->1) for the grow animation */\n introProgress: MotionValue<number>;\n /** Callback when the grow (stage1) completes */\n onIntroGrowComplete?: () => void;\n\n // ============== Intro Customization ==============\n /** Disable intro animation entirely (starts at full size) */\n skipIntro?: boolean;\n /** Custom intro content to show during loading */\n introContent?: ReactNode;\n /** Custom loading text (default: \"LOADING CANVAS\") */\n loadingText?: string;\n /** Background gradient for intro screen (CSS gradient string) */\n introBackgroundGradient?: string;\n /** Custom wrapper background component (overrides introBackgroundGradient if provided) */\n wrapperBackground?: ReactNode;\n /** Canvas box gradient for blur mask */\n canvasBoxGradient?: string;\n /** Grow animation transition config */\n growTransition?: Transition;\n /** Blur animation transition config */\n blurTransition?: Transition;\n}\n\nexport const CanvasWrapper = ({\n children,\n introProgress,\n onIntroGrowComplete,\n skipIntro = false,\n introContent,\n loadingText = \"LOADING CANVAS\",\n introBackgroundGradient = \"linear-gradient(to top, #d4d4d4 0%, #e5e5e5 50%, #f5f5f5 100%)\",\n wrapperBackground,\n canvasBoxGradient = \"radial-gradient(130.38% 95% at 50.03% 97.25%, #d4d4d4 0%, #e5e5e5 48.09%, #f5f5f5 100%)\",\n growTransition = GROW_TRANSITION,\n blurTransition = BLUR_TRANSITION,\n}: CanvasWrapperProps) => {\n const [dimensions, setDimensions] = useState<{\n width: number;\n height: number;\n } | null>(null);\n const [dots, setDots] = useState<string>(\"..\");\n const [stage1NotFinished, setStage1NotFinished] = useState(true);\n const completedRef = useRef(false);\n\n // If skipIntro is true, immediately complete the intro\n useEffect(() => {\n if (skipIntro && !completedRef.current) {\n completedRef.current = true;\n introProgress.set(1);\n onIntroGrowComplete?.();\n }\n }, [skipIntro, introProgress, onIntroGrowComplete]);\n\n // add up to 4 dots, then go back down to 2\n useEffect(() => {\n if (skipIntro) return; // Don't animate dots if skipping intro\n\n const interval = setInterval(() => {\n setDots((prevDots) => {\n if (prevDots.length < 3) {\n return prevDots + \".\";\n } else {\n return \".\";\n }\n });\n }, 500);\n return () => clearInterval(interval);\n }, [skipIntro]);\n\n useEffect(() => {\n if (skipIntro) return; // Don't calculate dimensions if skipping intro\n\n // calculate the initial 3:2 box size with margins (client-only)\n const calculateInitialSize = () => {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const maxWidth = vw * MAX_DIM_RATIO.width;\n const maxHeight = vh * MAX_DIM_RATIO.height;\n\n // width or height as limiter\n if (maxWidth / INTRO_ASPECT_RATIO <= maxHeight) {\n return { width: maxWidth, height: maxWidth / INTRO_ASPECT_RATIO };\n } else {\n return { height: maxHeight, width: maxHeight * INTRO_ASPECT_RATIO };\n }\n };\n\n setDimensions(calculateInitialSize());\n }, [skipIntro]);\n\n // If skipIntro, render children directly without animation wrapper\n if (skipIntro) {\n return (\n <motion.div\n className=\"fixed inset-0 overflow-hidden\"\n style={{\n touchAction: \"none\",\n userSelect: \"none\",\n pointerEvents: \"none\",\n }}\n onContextMenu={(e) => e.preventDefault()}\n >\n {children}\n </motion.div>\n );\n }\n\n return (\n <motion.div\n className=\"fixed inset-0 overflow-hidden\"\n style={{\n // Only use gradient style if no custom wrapperBackground is provided\n backgroundImage: stage1NotFinished && !wrapperBackground ? introBackgroundGradient : undefined,\n touchAction: \"none\",\n userSelect: \"none\",\n pointerEvents: \"none\",\n }}\n onContextMenu={(e) => e.preventDefault()}\n >\n {/* Custom wrapper background (renders behind everything) */}\n {stage1NotFinished && wrapperBackground}\n\n {stage1NotFinished && (\n <>\n {introContent}\n </>\n )}\n\n {dimensions && (\n <>\n {/* Blurring mask box */}\n <motion.div\n initial={{\n width: dimensions.width,\n height: dimensions.height,\n opacity: 1,\n backgroundImage: canvasBoxGradient,\n }}\n animate={{\n opacity: 0,\n display: \"none\",\n }}\n transition={blurTransition}\n className=\"absolute left-1/2 top-1/2 z-20 origin-center -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg\"\n />\n {/* Growing wrapper drives introProgress */}\n <motion.div\n initial={{\n width: dimensions.width,\n height: dimensions.height,\n }}\n animate={{\n width: \"100vw\",\n height: \"100vh\",\n }}\n transition={growTransition}\n onUpdate={(latest: { width?: number; height?: number }) => {\n if (completedRef.current) return;\n if (typeof latest.width === \"number\") {\n const w0 = dimensions.width;\n const w1 = window.innerWidth;\n const progress =\n w1 === w0 ? 1 : (latest.width - w0) / (w1 - w0);\n const clamped = Math.min(Math.max(progress, 0), 1);\n introProgress.set(clamped);\n }\n }}\n onAnimationComplete={() => {\n if (!completedRef.current) {\n completedRef.current = true;\n introProgress.set(1);\n setStage1NotFinished(false);\n onIntroGrowComplete?.();\n }\n }}\n className=\"absolute left-1/2 top-1/2 z-10 origin-center -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg shadow-[0_20px_40px_rgba(103,86,86,0.15)]\"\n >\n <div className=\"h-full w-full\">{children}</div>\n </motion.div>\n </>\n )}\n {stage1NotFinished && loadingText && (\n <div className=\"absolute bottom-24 left-1/2 -translate-x-1/2 text-center font-mono font-semibold text-neutral-500\">\n {loadingText}{dots}\n </div>\n )}\n </motion.div>\n );\n};\n"],"mappings":";;;;;;AAsCA,MAAa,iBAAiB,EAC5B,UACA,eACA,qBACA,YAAY,OACZ,cACA,cAAc,kBACd,0BAA0B,kEAC1B,mBACA,oBAAoB,2FACpB,iBAAiB,iBACjB,iBAAiB,sBACO;CACxB,MAAM,CAAC,YAAY,iBAAiB,SAG1B,KAAK;CACf,MAAM,CAAC,MAAM,WAAW,SAAiB,KAAK;CAC9C,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,KAAK;CAChE,MAAM,eAAe,OAAO,MAAM;AAGlC,iBAAgB;AACd,MAAI,aAAa,CAAC,aAAa,SAAS;AACtC,gBAAa,UAAU;AACvB,iBAAc,IAAI,EAAE;AACpB,0BAAuB;;IAExB;EAAC;EAAW;EAAe;EAAoB,CAAC;AAGnD,iBAAgB;AACd,MAAI,UAAW;EAEf,MAAM,WAAW,kBAAkB;AACjC,YAAS,aAAa;AACpB,QAAI,SAAS,SAAS,EACpB,QAAO,WAAW;QAElB,QAAO;KAET;KACD,IAAI;AACP,eAAa,cAAc,SAAS;IACnC,CAAC,UAAU,CAAC;AAEf,iBAAgB;AACd,MAAI,UAAW;EAGf,MAAM,6BAA6B;GACjC,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAElB,MAAM,WAAW,KAAK,cAAc;GACpC,MAAM,YAAY,KAAK,cAAc;AAGrC,OAAI,WAAW,sBAAsB,UACnC,QAAO;IAAE,OAAO;IAAU,QAAQ,WAAW;IAAoB;OAEjE,QAAO;IAAE,QAAQ;IAAW,OAAO,YAAY;IAAoB;;AAIvE,gBAAc,sBAAsB,CAAC;IACpC,CAAC,UAAU,CAAC;AAGf,KAAI,UACF,QACE,oBAAC,OAAO;EACN,WAAU;EACV,OAAO;GACL,aAAa;GACb,YAAY;GACZ,eAAe;GAChB;EACD,gBAAgB,MAAM,EAAE,gBAAgB;EAEvC;GACU;AAIjB,QACE,qBAAC,OAAO;EACN,WAAU;EACV,OAAO;GAEL,iBAAiB,qBAAqB,CAAC,oBAAoB,0BAA0B;GACrF,aAAa;GACb,YAAY;GACZ,eAAe;GAChB;EACD,gBAAgB,MAAM,EAAE,gBAAgB;;GAGvC,qBAAqB;GAErB,qBACC,0CACG,eACA;GAGJ,cACC,4CAEE,oBAAC,OAAO;IACN,SAAS;KACP,OAAO,WAAW;KAClB,QAAQ,WAAW;KACnB,SAAS;KACT,iBAAiB;KAClB;IACD,SAAS;KACP,SAAS;KACT,SAAS;KACV;IACD,YAAY;IACZ,WAAU;KACV,EAEF,oBAAC,OAAO;IACN,SAAS;KACP,OAAO,WAAW;KAClB,QAAQ,WAAW;KACpB;IACD,SAAS;KACP,OAAO;KACP,QAAQ;KACT;IACD,YAAY;IACZ,WAAW,WAAgD;AACzD,SAAI,aAAa,QAAS;AAC1B,SAAI,OAAO,OAAO,UAAU,UAAU;MACpC,MAAM,KAAK,WAAW;MACtB,MAAM,KAAK,OAAO;MAClB,MAAM,WACJ,OAAO,KAAK,KAAK,OAAO,QAAQ,OAAO,KAAK;MAC9C,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI,UAAU,EAAE,EAAE,EAAE;AAClD,oBAAc,IAAI,QAAQ;;;IAG9B,2BAA2B;AACzB,SAAI,CAAC,aAAa,SAAS;AACzB,mBAAa,UAAU;AACvB,oBAAc,IAAI,EAAE;AACpB,2BAAqB,MAAM;AAC3B,6BAAuB;;;IAG3B,WAAU;cAEV,oBAAC;KAAI,WAAU;KAAiB;MAAe;KACpC,IACZ;GAEJ,qBAAqB,eACpB,qBAAC;IAAI,WAAU;eACZ,aAAa;KACV;;GAEG"}
@@ -1,22 +1,30 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
1
  import React, { createContext, useContext } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+
4
+ //#region src/contexts/CanvasContext.tsx
3
5
  const defaultState = {
4
- x: undefined,
5
- y: undefined,
6
- scale: 1,
7
- isResetting: false,
8
- maxZIndex: 1,
9
- setMaxZIndex: () => {
10
- console.log("setMaxZIndex not set");
11
- },
12
- animationStage: 0,
13
- nextTargetSection: null,
14
- setNextTargetSection: () => {
15
- console.log("setNextTargetSection not set");
16
- },
6
+ x: void 0,
7
+ y: void 0,
8
+ scale: 1,
9
+ isResetting: false,
10
+ maxZIndex: 1,
11
+ setMaxZIndex: () => {
12
+ console.log("setMaxZIndex not set");
13
+ },
14
+ animationStage: 0,
15
+ nextTargetSection: null,
16
+ setNextTargetSection: () => {
17
+ console.log("setNextTargetSection not set");
18
+ }
17
19
  };
18
- export const CanvasContext = createContext(defaultState);
19
- export const useCanvasContext = () => useContext(CanvasContext);
20
- export const CanvasProvider = React.memo(({ children, ...value }) => (_jsx(CanvasContext.Provider, { value: value, children: children })));
20
+ const CanvasContext = createContext(defaultState);
21
+ const useCanvasContext = () => useContext(CanvasContext);
22
+ const CanvasProvider = React.memo(({ children, ...value }) => /* @__PURE__ */ jsx(CanvasContext.Provider, {
23
+ value,
24
+ children
25
+ }));
21
26
  CanvasProvider.displayName = "CanvasProvider";
27
+
28
+ //#endregion
29
+ export { CanvasContext, CanvasProvider, useCanvasContext };
22
30
  //# sourceMappingURL=CanvasContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasContext.js","sourceRoot":"","sources":["../../src/contexts/CanvasContext.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAC;AAqBzE,MAAM,YAAY,GAAG;IACnB,CAAC,EAAE,SAA2C;IAC9C,CAAC,EAAE,SAA2C;IAC9C,KAAK,EAAE,CAAmC;IAC1C,WAAW,EAAE,KAAK;IAClB,SAAS,EAAE,CAAC;IACZ,YAAY,EAAE,GAAG,EAAE;QACjB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;IACD,cAAc,EAAE,CAAC;IACjB,iBAAiB,EAAE,IAAI;IACvB,oBAAoB,EAAE,GAAG,EAAE;QACzB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC9C,CAAC;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAqB,YAAY,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAMhE,MAAM,CAAC,MAAM,cAAc,GAAkC,KAAK,CAAC,IAAI,CACrE,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC,CAC1B,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,KAA2B,YACvD,QAAQ,GACc,CAC1B,CACF,CAAC;AAEF,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAC"}
1
+ {"version":3,"file":"CanvasContext.js","names":[],"sources":["../../src/contexts/CanvasContext.tsx"],"sourcesContent":["import React, { createContext, useContext, type ReactNode } from \"react\";\nimport { type MotionValue } from \"framer-motion\";\nimport { CanvasSection } from \"../types\";\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface CanvasContextState {\n x: MotionValue<number>;\n y: MotionValue<number>;\n scale: MotionValue<number>;\n isResetting: boolean;\n maxZIndex: number;\n setMaxZIndex: (zIndex: number) => void;\n animationStage: number;\n nextTargetSection: CanvasSection | null; // predictive pre-render target\n setNextTargetSection: (section: CanvasSection | null) => void;\n}\n\nconst defaultState = {\n x: undefined as unknown as MotionValue<number>,\n y: undefined as unknown as MotionValue<number>,\n scale: 1 as unknown as MotionValue<number>,\n isResetting: false,\n maxZIndex: 1,\n setMaxZIndex: () => {\n console.log(\"setMaxZIndex not set\");\n },\n animationStage: 0,\n nextTargetSection: null,\n setNextTargetSection: () => {\n console.log(\"setNextTargetSection not set\");\n },\n} as const;\n\nexport const CanvasContext = createContext<CanvasContextState>(defaultState);\n\nexport const useCanvasContext = () => useContext(CanvasContext);\n\ninterface CanvasProviderProps extends CanvasContextState {\n children: ReactNode;\n}\n\nexport const CanvasProvider: React.FC<CanvasProviderProps> = React.memo(\n ({ children, ...value }) => (\n <CanvasContext.Provider value={value as CanvasContextState}>\n {children}\n </CanvasContext.Provider>\n ),\n);\n\nCanvasProvider.displayName = \"CanvasProvider\";\n"],"mappings":";;;;AAqBA,MAAM,eAAe;CACnB,GAAG;CACH,GAAG;CACH,OAAO;CACP,aAAa;CACb,WAAW;CACX,oBAAoB;AAClB,UAAQ,IAAI,uBAAuB;;CAErC,gBAAgB;CAChB,mBAAmB;CACnB,4BAA4B;AAC1B,UAAQ,IAAI,+BAA+B;;CAE9C;AAED,MAAa,gBAAgB,cAAkC,aAAa;AAE5E,MAAa,yBAAyB,WAAW,cAAc;AAM/D,MAAa,iBAAgD,MAAM,MAChE,EAAE,UAAU,GAAG,YACd,oBAAC,cAAc;CAAgB;CAC5B;EACsB,CAE5B;AAED,eAAe,cAAc"}