@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.
- package/README.md +196 -8
- package/dist/components/canvas/backgrounds.d.ts +4 -4
- package/dist/components/canvas/backgrounds.d.ts.map +1 -1
- package/dist/components/canvas/backgrounds.js +68 -39
- package/dist/components/canvas/backgrounds.js.map +1 -1
- package/dist/components/canvas/canvas.d.ts +3 -1
- package/dist/components/canvas/canvas.d.ts.map +1 -1
- package/dist/components/canvas/canvas.js +451 -387
- package/dist/components/canvas/canvas.js.map +1 -1
- package/dist/components/canvas/component.js +108 -174
- package/dist/components/canvas/component.js.map +1 -1
- package/dist/components/canvas/draggable.js +168 -151
- package/dist/components/canvas/draggable.js.map +1 -1
- package/dist/components/canvas/navbar/index.d.ts +4 -2
- package/dist/components/canvas/navbar/index.d.ts.map +1 -1
- package/dist/components/canvas/navbar/index.js +168 -101
- package/dist/components/canvas/navbar/index.js.map +1 -1
- package/dist/components/canvas/navbar/single-button.d.ts +10 -1
- package/dist/components/canvas/navbar/single-button.d.ts.map +1 -1
- package/dist/components/canvas/navbar/single-button.js +176 -69
- package/dist/components/canvas/navbar/single-button.js.map +1 -1
- package/dist/components/canvas/toolbar.js +121 -82
- package/dist/components/canvas/toolbar.js.map +1 -1
- package/dist/components/canvas/wrapper.js +127 -99
- package/dist/components/canvas/wrapper.js.map +1 -1
- package/dist/contexts/CanvasContext.js +25 -17
- package/dist/contexts/CanvasContext.js.map +1 -1
- package/dist/contexts/PerformanceContext.js +51 -50
- package/dist/contexts/PerformanceContext.js.map +1 -1
- package/dist/hooks/usePerformanceMode.js +36 -37
- package/dist/hooks/usePerformanceMode.js.map +1 -1
- package/dist/hooks/useWindowDimensions.js +22 -18
- package/dist/hooks/useWindowDimensions.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -21
- package/dist/lib/canvas.js +65 -72
- package/dist/lib/canvas.js.map +1 -1
- package/dist/lib/constants.js +78 -92
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/utils.js +10 -5
- package/dist/lib/utils.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/index.d.ts +69 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/performance.js +18 -23
- package/dist/utils/performance.js.map +1 -1
- package/package.json +7 -21
- package/src/components/canvas/backgrounds.tsx +7 -7
- package/src/components/canvas/canvas.tsx +9 -2
- package/src/components/canvas/navbar/index.tsx +91 -15
- package/src/components/canvas/navbar/single-button.tsx +210 -56
- package/src/index.ts +5 -0
- package/src/styles.css +15 -13
- package/src/types/index.ts +91 -0
- package/dist/components/canvas/offest.js +0 -12
- package/dist/components/canvas/offest.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types/index.js +0 -6
- package/dist/types/index.js.map +0 -1
|
@@ -1,86 +1,125 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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 = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
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","
|
|
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 {
|
|
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 {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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","
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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","
|
|
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"}
|