@hunterchen/canvas 0.8.0 → 0.10.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 (48) hide show
  1. package/dist/components/canvas/backgrounds.js +67 -38
  2. package/dist/components/canvas/backgrounds.js.map +1 -1
  3. package/dist/components/canvas/canvas.d.ts +2 -0
  4. package/dist/components/canvas/canvas.d.ts.map +1 -1
  5. package/dist/components/canvas/canvas.js +459 -387
  6. package/dist/components/canvas/canvas.js.map +1 -1
  7. package/dist/components/canvas/component.js +108 -174
  8. package/dist/components/canvas/component.js.map +1 -1
  9. package/dist/components/canvas/draggable.js +168 -151
  10. package/dist/components/canvas/draggable.js.map +1 -1
  11. package/dist/components/canvas/navbar/index.js +164 -142
  12. package/dist/components/canvas/navbar/index.js.map +1 -1
  13. package/dist/components/canvas/navbar/single-button.js +176 -149
  14. package/dist/components/canvas/navbar/single-button.js.map +1 -1
  15. package/dist/components/canvas/toolbar.js +121 -82
  16. package/dist/components/canvas/toolbar.js.map +1 -1
  17. package/dist/components/canvas/wrapper.js +127 -99
  18. package/dist/components/canvas/wrapper.js.map +1 -1
  19. package/dist/contexts/CanvasContext.js +25 -17
  20. package/dist/contexts/CanvasContext.js.map +1 -1
  21. package/dist/contexts/PerformanceContext.js +51 -50
  22. package/dist/contexts/PerformanceContext.js.map +1 -1
  23. package/dist/hooks/usePerformanceMode.js +36 -37
  24. package/dist/hooks/usePerformanceMode.js.map +1 -1
  25. package/dist/hooks/useWindowDimensions.js +22 -18
  26. package/dist/hooks/useWindowDimensions.js.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +17 -21
  30. package/dist/lib/canvas.js +65 -72
  31. package/dist/lib/canvas.js.map +1 -1
  32. package/dist/lib/constants.js +78 -92
  33. package/dist/lib/constants.js.map +1 -1
  34. package/dist/lib/utils.js +10 -5
  35. package/dist/lib/utils.js.map +1 -1
  36. package/dist/types/index.d.ts +22 -0
  37. package/dist/types/index.d.ts.map +1 -1
  38. package/dist/utils/performance.js +18 -23
  39. package/dist/utils/performance.js.map +1 -1
  40. package/package.json +7 -21
  41. package/src/components/canvas/canvas.tsx +16 -4
  42. package/src/index.ts +1 -0
  43. package/src/types/index.ts +24 -0
  44. package/dist/components/canvas/offest.js +0 -12
  45. package/dist/components/canvas/offest.js.map +0 -1
  46. package/dist/index.js.map +0 -1
  47. package/dist/types/index.js +0 -6
  48. package/dist/types/index.js.map +0 -1
@@ -1,29 +1,24 @@
1
+ //#region src/utils/performance.ts
1
2
  /**
2
- * Performance optimization utilities for cross-platform compatibility
3
- * Particularly focused on iOS Safari performance issues
4
- */
5
- // Detect if the device is iOS
6
- export const isIOS = () => {
7
- if (typeof window === "undefined")
8
- return false;
9
- return /iPad|iPhone|iPod/.test(navigator.userAgent);
3
+ * Performance optimization utilities for cross-platform compatibility
4
+ * Particularly focused on iOS Safari performance issues
5
+ */
6
+ const isIOS = () => {
7
+ if (typeof window === "undefined") return false;
8
+ return /iPad|iPhone|iPod/.test(navigator.userAgent);
10
9
  };
11
- // Detect if the device is a mobile device
12
- export const isMobile = () => {
13
- if (typeof window === "undefined")
14
- return false;
15
- return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
10
+ const isMobile = () => {
11
+ if (typeof window === "undefined") return false;
12
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
16
13
  };
17
- // Check if user prefers reduced motion
18
- export const prefersReducedMotion = () => {
19
- if (typeof window === "undefined")
20
- return false;
21
- return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
14
+ const prefersReducedMotion = () => {
15
+ if (typeof window === "undefined") return false;
16
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
22
17
  };
23
- // Get optimized will-change value based on state
24
- export const getWillChange = (isAnimating, properties = ["transform"]) => {
25
- // Only apply will-change when actually animating
26
- // Leaving it on causes memory issues on iOS
27
- return isAnimating ? properties.join(", ") : "auto";
18
+ const getWillChange = (isAnimating, properties = ["transform"]) => {
19
+ return isAnimating ? properties.join(", ") : "auto";
28
20
  };
21
+
22
+ //#endregion
23
+ export { getWillChange, isIOS, isMobile, prefersReducedMotion };
29
24
  //# sourceMappingURL=performance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"performance.js","sourceRoot":"","sources":["../../src/utils/performance.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8BAA8B;AAC9B,MAAM,CAAC,MAAM,KAAK,GAAG,GAAY,EAAE;IACjC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAEhD,OAAO,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AACtD,CAAC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAY,EAAE;IACpC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAEhD,OAAO,gEAAgE,CAAC,IAAI,CAC1E,SAAS,CAAC,SAAS,CACpB,CAAC;AACJ,CAAC,CAAC;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAY,EAAE;IAChD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAEhD,OAAO,MAAM,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAC,OAAO,CAAC;AACvE,CAAC,CAAC;AAEF,iDAAiD;AACjD,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,WAAoB,EACpB,aAAuB,CAAC,WAAW,CAAC,EAC5B,EAAE;IACV,iDAAiD;IACjD,4CAA4C;IAC5C,OAAO,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACtD,CAAC,CAAC"}
1
+ {"version":3,"file":"performance.js","names":[],"sources":["../../src/utils/performance.ts"],"sourcesContent":["/**\n * Performance optimization utilities for cross-platform compatibility\n * Particularly focused on iOS Safari performance issues\n */\n\n// Detect if the device is iOS\nexport const isIOS = (): boolean => {\n if (typeof window === \"undefined\") return false;\n\n return /iPad|iPhone|iPod/.test(navigator.userAgent);\n};\n\n// Detect if the device is a mobile device\nexport const isMobile = (): boolean => {\n if (typeof window === \"undefined\") return false;\n\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n navigator.userAgent,\n );\n};\n\n// Check if user prefers reduced motion\nexport const prefersReducedMotion = (): boolean => {\n if (typeof window === \"undefined\") return false;\n\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n};\n\n// Get optimized will-change value based on state\nexport const getWillChange = (\n isAnimating: boolean,\n properties: string[] = [\"transform\"],\n): string => {\n // Only apply will-change when actually animating\n // Leaving it on causes memory issues on iOS\n return isAnimating ? properties.join(\", \") : \"auto\";\n};\n"],"mappings":";;;;;AAMA,MAAa,cAAuB;AAClC,KAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAO,mBAAmB,KAAK,UAAU,UAAU;;AAIrD,MAAa,iBAA0B;AACrC,KAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAO,iEAAiE,KACtE,UAAU,UACX;;AAIH,MAAa,6BAAsC;AACjD,KAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAO,OAAO,WAAW,mCAAmC,CAAC;;AAI/D,MAAa,iBACX,aACA,aAAuB,CAAC,YAAY,KACzB;AAGX,QAAO,cAAc,WAAW,KAAK,KAAK,GAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunterchen/canvas",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "A React-based canvas library for creating pannable, zoomable, and interactive canvas experiences.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,30 +17,15 @@
17
17
  "exports": {
18
18
  ".": {
19
19
  "types": "./dist/index.d.ts",
20
- "default": "./dist/index.js"
20
+ "import": "./dist/index.js"
21
21
  },
22
- "./styles.css": "./dist/styles.css",
23
- "./components": {
24
- "types": "./dist/components/index.d.ts",
25
- "default": "./dist/components/index.js"
26
- },
27
- "./contexts": {
28
- "types": "./dist/contexts/index.d.ts",
29
- "default": "./dist/contexts/index.js"
30
- },
31
- "./hooks": {
32
- "types": "./dist/hooks/index.d.ts",
33
- "default": "./dist/hooks/index.js"
34
- },
35
- "./lib": {
36
- "types": "./dist/lib/index.d.ts",
37
- "default": "./dist/lib/index.js"
38
- }
22
+ "./styles.css": "./dist/styles.css"
39
23
  },
40
24
  "scripts": {
41
- "build": "npm run clean && npm run build:css && npm run build:ts",
25
+ "build": "npm run clean && npm run build:css && npm run build:js && npm run build:types",
42
26
  "build:css": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify",
43
- "build:ts": "tsc",
27
+ "build:js": "rolldown -c",
28
+ "build:types": "tsc --emitDeclarationOnly",
44
29
  "type-check": "tsc --noEmit",
45
30
  "clean": "rm -rf dist"
46
31
  },
@@ -61,6 +46,7 @@
61
46
  "framer-motion": "^12.26.2",
62
47
  "react": "^19.2.3",
63
48
  "react-dom": "^19.2.3",
49
+ "rolldown": "^1.0.0-rc.2",
64
50
  "tailwindcss": "^3.4.19",
65
51
  "tailwindcss-animate": "^1.0.7",
66
52
  "typescript": "^5.8.2"
@@ -80,6 +80,8 @@ interface Props {
80
80
  growTransition?: Transition;
81
81
  /** Custom blur transition */
82
82
  blurTransition?: Transition;
83
+ /** Custom pan-to-home transition (stage 2) */
84
+ panTransition?: Transition;
83
85
 
84
86
  // ============== Background Customization ==============
85
87
  /** Custom canvas background. If not provided, uses DefaultCanvasBackground. */
@@ -117,6 +119,7 @@ const Canvas: FC<Props> = ({
117
119
  canvasBoxGradient,
118
120
  growTransition,
119
121
  blurTransition,
122
+ panTransition,
120
123
  canvasBackground,
121
124
  wrapperBackground,
122
125
  toolbarConfig,
@@ -225,14 +228,23 @@ const Canvas: FC<Props> = ({
225
228
  };
226
229
  }, [derivedScale, derivedX, derivedY, animationStage, scale, x, y]);
227
230
 
231
+ // Merge custom panTransition with defaults
232
+ const effectivePanTransition: Transition = useMemo(() => {
233
+ if (!panTransition) return STAGE2_TRANSITION;
234
+ return {
235
+ ...STAGE2_TRANSITION,
236
+ ...panTransition,
237
+ };
238
+ }, [panTransition]);
239
+
228
240
  // Kick off stage2 (pan to home) when grow completes (introProgress hits 1)
229
241
  const startStage2 = useCallback(() => {
230
242
  setAnimationStage(1);
231
243
 
232
244
  Promise.all([
233
- animate(x, offsetHomeCoordinates.x, STAGE2_TRANSITION),
234
- animate(y, offsetHomeCoordinates.y, STAGE2_TRANSITION),
235
- animate(scale, 1, STAGE2_TRANSITION),
245
+ animate(x, offsetHomeCoordinates.x, effectivePanTransition),
246
+ animate(y, offsetHomeCoordinates.y, effectivePanTransition),
247
+ animate(scale, 1, effectivePanTransition),
236
248
  ])
237
249
  .then(() => {
238
250
  setAnimationStage(2);
@@ -241,7 +253,7 @@ const Canvas: FC<Props> = ({
241
253
  .catch(() => {
242
254
  isIntroAnimatingRef.current = false;
243
255
  });
244
- }, [offsetHomeCoordinates, x, y, scale]);
256
+ }, [offsetHomeCoordinates, x, y, scale, effectivePanTransition]);
245
257
 
246
258
  const viewportRef = useRef<HTMLDivElement>(null);
247
259
  const sceneRef = useRef<HTMLDivElement>(null);
package/src/index.ts CHANGED
@@ -61,4 +61,5 @@ export type {
61
61
  NavbarDisplayMode,
62
62
  NavbarButtonConfig,
63
63
  NavbarTooltipConfig,
64
+ AnimationTimingConfig,
64
65
  } from "./types";
@@ -3,6 +3,8 @@
3
3
  * Apps should extend these types with their specific enums and constants
4
4
  */
5
5
 
6
+ import type { Transition } from "framer-motion";
7
+
6
8
  export interface SectionCoordinates {
7
9
  x: number;
8
10
  y: number;
@@ -152,6 +154,28 @@ export interface NavbarButtonConfig {
152
154
  labelStyle?: React.CSSProperties;
153
155
  }
154
156
 
157
+ /**
158
+ * Animation timing configuration for intro animations.
159
+ * Re-exports Framer Motion's Transition type for full flexibility.
160
+ *
161
+ * @example
162
+ * // Simple duration-based transition
163
+ * const timing: AnimationTimingConfig = {
164
+ * duration: 1.5,
165
+ * delay: 0.5,
166
+ * ease: "easeInOut"
167
+ * };
168
+ *
169
+ * @example
170
+ * // Custom bezier curve
171
+ * const timing: AnimationTimingConfig = {
172
+ * duration: 0.96,
173
+ * delay: 3.14,
174
+ * ease: [0.35, 0.1, 0.8, 1]
175
+ * };
176
+ */
177
+ export type AnimationTimingConfig = Transition;
178
+
155
179
  /**
156
180
  * Configuration options for the canvas navbar
157
181
  */
@@ -1,12 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { motion } from "framer-motion";
3
- export const OffsetComponent = ({ offset, children, }) => {
4
- return (_jsx(motion.div, { style: {
5
- position: "absolute",
6
- top: offset.y,
7
- left: offset.x,
8
- width: "100%",
9
- height: "100%",
10
- }, children: children }));
11
- };
12
- //# sourceMappingURL=offest.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"offest.js","sourceRoot":"","sources":["../../../src/components/canvas/offest.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,eAAe,CAAC;AAEnD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,MAAM,EACN,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO,CACL,KAAC,MAAM,CAAC,GAAG,IACT,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,MAAM,CAAC,CAAC;YACb,IAAI,EAAE,MAAM,CAAC,CAAC;YACd,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,MAAM;SACf,YAEA,QAAQ,GACE,CACd,CAAC;AACJ,CAAC,CAAC"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAErE,wBAAwB;AACxB,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,iCAAiC,CAAC;AAOzC,WAAW;AACX,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,GACf,MAAM,+BAA+B,CAAC;AAMvC,QAAQ;AACR,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,kBAAkB,IAAI,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAE5F,YAAY;AACZ,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Generic types for the canvas library
3
- * Apps should extend these types with their specific enums and constants
4
- */
5
- export {};
6
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG"}