react-gsap-aos 1.3.0 → 1.4.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 CHANGED
@@ -28,7 +28,7 @@ While AOS is great for vanilla JavaScript, integrating it with React can be prob
28
28
  - Limited TypeScript support
29
29
  - Difficult to use with dynamic content
30
30
 
31
- `react-gsap-aos` solves these issues by providing a React-native solution that automatically handles DOM mutations, component lifecycle, and SSR scenarios.
31
+ `react-gsap-aos` by React solution that automatically handles DOM mutations, component lifecycle, and SSR scenarios.
32
32
 
33
33
  ## Features
34
34
 
@@ -281,17 +281,15 @@ const props = toAOSProps({
281
281
  // Returns: { "data-aos": "fade-up", "data-aos-duration": 600, ... }
282
282
  ```
283
283
 
284
- ### refreshAOS
284
+ ### refreshScrollTrigger
285
285
 
286
- Manually refresh AOS animation positions (currently a wrapper around `ScrollTrigger.refresh`).
287
-
288
- > ⚠️ Note: The current behavior is identical to GSAP's native `ScrollTrigger.refresh`. The wrapper exists to unify the API and allow future custom logic.
286
+ Manually refresh AOS animation positions, wrapper around [`ScrollTrigger.refresh`](<https://gsap.com/docs/v3/Plugins/ScrollTrigger/refresh()>).
289
287
 
290
288
  ```tsx
291
- import { refreshAOS } from "react-gsap-aos";
289
+ import { refreshScrollTrigger } from "react-gsap-aos";
292
290
 
293
291
  // Call after dynamic DOM changes
294
- refreshAOS();
292
+ refreshScrollTrigger();
295
293
  ```
296
294
 
297
295
  **Example with Dynamic Content:**
@@ -338,6 +336,7 @@ export default function DynamicList() {
338
336
  | `once` | `boolean` | `data-aos-once` | `false` | Animate only once |
339
337
  | `mirror` | `boolean` | `data-aos-mirror` | `false` | Reverse animation on scroll up |
340
338
  | `anchorPlacement` | `AnchorPlacement` | `data-aos-anchor-placement` | `"top-bottom"` | Trigger position |
339
+ | `markers` | `boolean` | `data-aos-markers` | `false` | ScrollTrigger markers |
341
340
 
342
341
  ## Available Types
343
342
 
package/README.zh-TW.md CHANGED
@@ -28,7 +28,7 @@
28
28
  - TypeScript 支援有限
29
29
  - 難以處理動態內容
30
30
 
31
- `react-gsap-aos` 透過提供 React 原生解決方案來解決這些問題,自動處理 DOM 變更、元件生命週期和 SSR 場景。
31
+ `react-gsap-aos` 透過 React 來解決這些問題,自動處理 DOM 變更、元件生命週期和 SSR 場景。
32
32
 
33
33
  ## 功能特色
34
34
 
@@ -279,17 +279,15 @@ const props = toAOSProps({
279
279
  // 回傳:{ "data-aos": "fade-up", "data-aos-duration": 600, ... }
280
280
  ```
281
281
 
282
- ### refreshAOS
282
+ ### refreshScrollTrigger
283
283
 
284
- 手動刷新 AOS 動畫位置(目前封裝自 `ScrollTrigger.refresh`)。
285
-
286
- > ⚠️ 注意:目前行為與 GSAP 原生 `ScrollTrigger.refresh` 相同,名稱封裝是為了統一 API 與未來可擴展額外邏輯。
284
+ 手動刷新 AOS 動畫位置,封裝自 [`ScrollTrigger.refresh`](<https://gsap.com/docs/v3/Plugins/ScrollTrigger/refresh()>)
287
285
 
288
286
  ```tsx
289
- import { refreshAOS } from "react-gsap-aos";
287
+ import { refreshScrollTrigger } from "react-gsap-aos";
290
288
 
291
289
  // 在動態 DOM 變更後呼叫
292
- refreshAOS();
290
+ refreshScrollTrigger();
293
291
  ```
294
292
 
295
293
  **動態內容範例:**
@@ -336,6 +334,7 @@ export default function DynamicList() {
336
334
  | `once` | `boolean` | `data-aos-once` | `false` | 只執行一次動畫 |
337
335
  | `mirror` | `boolean` | `data-aos-mirror` | `false` | 向上捲動時反轉動畫 |
338
336
  | `anchorPlacement` | `AnchorPlacement` | `data-aos-anchor-placement` | `"top-bottom"` | 錨點位置 |
337
+ | `markers` | `boolean` | `data-aos-markers` | `false` | ScrollTrigger 標記 |
339
338
 
340
339
  ## 可用型別
341
340
 
package/dist/client.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentPropsWithoutRef } from 'react';
3
- import { A as AnimationOptions } from './types-D2cyob0n.mjs';
3
+ import { A as AnimationOptions } from './types-CQ3qrMsE.mjs';
4
4
 
5
5
  type UseAOSScopeOptions = Partial<AnimationOptions>;
6
6
  /**
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentPropsWithoutRef } from 'react';
3
- import { A as AnimationOptions } from './types-D2cyob0n.js';
3
+ import { A as AnimationOptions } from './types-CQ3qrMsE.js';
4
4
 
5
5
  type UseAOSScopeOptions = Partial<AnimationOptions>;
6
6
  /**
package/dist/client.js CHANGED
@@ -82,7 +82,8 @@ var DEFAULT_OPTIONS = {
82
82
  easing: "none",
83
83
  once: false,
84
84
  mirror: false,
85
- anchorPlacement: "top-bottom"
85
+ anchorPlacement: "top-bottom",
86
+ markers: false
86
87
  };
87
88
  var easings = [
88
89
  "none",
@@ -147,7 +148,8 @@ var AOS_ATTRIBUTE_MAP = {
147
148
  "data-aos-easing": "easing",
148
149
  "data-aos-mirror": "mirror",
149
150
  "data-aos-once": "once",
150
- "data-aos-anchor-placement": "anchorPlacement"
151
+ "data-aos-anchor-placement": "anchorPlacement",
152
+ "data-aos-markers": "markers"
151
153
  };
152
154
  function parseAttributes(element) {
153
155
  const options = {};
@@ -165,26 +167,25 @@ function parseAttributes(element) {
165
167
  }
166
168
  break;
167
169
  case "once":
168
- case "mirror": {
170
+ case "mirror":
171
+ case "markers":
169
172
  const booleanValue = parseBoolean(value);
170
173
  if (typeof booleanValue === "boolean") {
171
174
  options[prop] = booleanValue;
172
175
  }
173
176
  break;
174
- }
175
177
  case "easing":
176
178
  const easing = parseEnum(easings, value);
177
179
  if (easing) {
178
180
  options[prop] = easing;
179
181
  }
180
182
  break;
181
- case "anchorPlacement": {
183
+ case "anchorPlacement":
182
184
  const anchorPlacement = parseEnum(anchorPlacements, value);
183
185
  if (anchorPlacement) {
184
186
  options[prop] = anchorPlacement;
185
187
  }
186
188
  break;
187
- }
188
189
  }
189
190
  }
190
191
  }
@@ -228,6 +229,7 @@ function mergeOptions(...array) {
228
229
  break;
229
230
  case "once":
230
231
  case "mirror":
232
+ case "markers":
231
233
  if (typeof value === "boolean") {
232
234
  result[key] = value;
233
235
  }
@@ -514,7 +516,16 @@ var UNIT_MS = 1e3;
514
516
  function createScrollTriggerTween(element, preset, vars, options) {
515
517
  const { from, to } = vars;
516
518
  const { parentElement } = element;
517
- const { offset, delay, duration, easing, once, mirror, anchorPlacement } = mergeOptions(options);
519
+ const {
520
+ offset,
521
+ delay,
522
+ duration,
523
+ easing,
524
+ once,
525
+ mirror,
526
+ anchorPlacement,
527
+ markers
528
+ } = mergeOptions(options);
518
529
  return import_gsap.default.fromTo(
519
530
  element,
520
531
  __spreadValues(__spreadValues({}, preset.from), from),
@@ -524,7 +535,7 @@ function createScrollTriggerTween(element, preset, vars, options) {
524
535
  delay: delay / UNIT_MS,
525
536
  overwrite: "auto",
526
537
  scrollTrigger: {
527
- // markers: true,
538
+ markers,
528
539
  invalidateOnRefresh: true,
529
540
  // 優先使用上一層被標記的動畫容器
530
541
  trigger: (parentElement == null ? void 0 : parentElement.hasAttribute("data-aos-container")) ? parentElement : element,
@@ -594,7 +605,8 @@ var AOS_ATTRIBUTE_KEYS = [
594
605
  "data-aos-easing",
595
606
  "data-aos-mirror",
596
607
  "data-aos-once",
597
- "data-aos-anchor-placement"
608
+ "data-aos-anchor-placement",
609
+ "data-aos-markers"
598
610
  ];
599
611
  var AOS_QUALIFIED_NAME = "data-aos";
600
612
  var AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;
@@ -639,13 +651,10 @@ function useAOSScope(options) {
639
651
  const addedElements = /* @__PURE__ */ new Set();
640
652
  const updatedElements = /* @__PURE__ */ new Set();
641
653
  for (const mutation of mutations) {
642
- const { type, target, addedNodes, removedNodes, attributeName } = mutation;
654
+ const { type, target, addedNodes, removedNodes } = mutation;
643
655
  if (type === "attributes" && target instanceof HTMLElement) {
644
656
  if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;
645
657
  updatedElements.add(target);
646
- if (attributeName === "data-aos-anchor-placement" || attributeName === "data-aos-offset") {
647
- shouldRefreshRef.current = true;
648
- }
649
658
  } else if (type === "childList") {
650
659
  collectElements(addedNodes, addedElements);
651
660
  collectElements(removedNodes, removedElements);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/components/AOSProvider.tsx","../src/hooks/useAOSScope.ts","../src/animation/constants.ts","../src/animation/utils/parseAttributes.ts","../src/animation/animations.ts","../src/animation/utils/mergeOptions.ts","../src/animation/utils/createTweenVars.ts","../src/animation/definitions.ts","../src/animation/createAnimation.ts","../src/utils/isBlockElementTag.ts"],"sourcesContent":["\"use client\";\n\nexport { default as AOSProvider } from \"./components/AOSProvider\";\nexport { default as useAOSScope } from \"./hooks/useAOSScope\";\n","\"use client\";\n\nimport { type ComponentPropsWithoutRef, createElement } from \"react\";\n\nimport useAOSScope, { type UseAOSScopeOptions } from \"@/hooks/useAOSScope\";\nimport isBlockElementTag, {\n type BlockElementTag,\n} from \"@/utils/isBlockElementTag\";\n\ntype AOSProviderProps<T extends BlockElementTag> = {\n /**\n * 要渲染的 HTML 元素標籤。\n *\n * 如果未提供或非區塊元素,預設會渲染 `<div>`。\n *\n * @default \"div\"\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n */\n component?: T;\n /**\n * 讓子元素繼承的預設動畫參數\n *\n * > 注意:預設選項只作用於後續生成的動畫,這是刻意設計的行為。\n */\n options?: UseAOSScopeOptions;\n} & ComponentPropsWithoutRef<T>;\n\n/**\n * 為子元素提供自動 AOS 動畫能力。\n *\n * 所有帶有 `data-aos` 屬性的子元素都會自動生成動畫。\n */\nexport default function AOSProvider<T extends BlockElementTag = \"div\">({\n component,\n options,\n children,\n ...props\n}: AOSProviderProps<T>) {\n const { containerRef } = useAOSScope(options);\n\n return createElement(\n isBlockElementTag(component) ? component : \"div\",\n { ...props, ref: containerRef },\n children,\n );\n}\n","import { useLayoutEffect, useRef } from \"react\";\nimport { useGSAP } from \"@gsap/react\";\nimport gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\nimport createAnimation from \"@/animation/createAnimation\";\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ngsap.registerPlugin(useGSAP, ScrollTrigger);\n\nexport type UseAOSScopeOptions = Partial<AnimationOptions>;\n\n/** AOS 屬性 */\nconst AOS_ATTRIBUTE_KEYS: (AOSAttributeKey | \"data-aos\")[] = [\n \"data-aos\",\n \"data-aos-offset\",\n \"data-aos-delay\",\n \"data-aos-duration\",\n \"data-aos-easing\",\n \"data-aos-mirror\",\n \"data-aos-once\",\n \"data-aos-anchor-placement\",\n];\n/** AOS 屬性名稱 */\nconst AOS_QUALIFIED_NAME = \"data-aos\";\n/** AOS 選擇器 */\nconst AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;\n\n/**\n * 綁定 AOS 動畫範圍\n * \n * @example\n * ```tsx\n \"use client\";\n\n import {useAOSScope} from '@/aos';\n \n export default function Demo() {\n const {containerRef} = useAOSScope<HTMLDivElement>()\n return (\n <div ref={containerRef} className=\"overflow-hidden\">\n <div data-aos-container>\n <div data-aos=\"fade-up\">Hello AOS</div>\n </div>\n </div>\n )\n }\n * ```\n */\nexport default function useAOSScope<E extends HTMLElement = HTMLElement>(\n /** 預設動畫選項 */\n options?: UseAOSScopeOptions,\n) {\n const containerRef = useRef<E | null>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n /** 記錄每個元素對應的動畫實例 */\n const elementAnimationsRef = useRef<WeakMap<HTMLElement, gsap.core.Tween>>(\n new WeakMap(),\n );\n const currentOptionsRef = useRef(options);\n const rafIdRef = useRef<number>(0);\n const shouldRefreshRef = useRef(false);\n\n // 下次新增動畫才會套用覆蓋預設值\n useLayoutEffect(() => {\n currentOptionsRef.current = options;\n }, [options]);\n\n useGSAP(\n (_, contextSafe) => {\n if (!containerRef.current || !contextSafe) return;\n\n /** 新增動畫 */\n const addAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n if (elementAnimations.has(element)) return;\n\n const newAnimation = contextSafe(createAnimation)(\n element,\n currentOptionsRef.current,\n );\n if (!newAnimation) return;\n\n elementAnimations.set(element, newAnimation);\n };\n\n /** 移除動畫 */\n const removeAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n const animation = elementAnimations.get(element);\n if (!animation) return;\n\n animation.revert();\n elementAnimations.delete(element);\n };\n\n /** 更新動畫 */\n const updateAnimation = (element: HTMLElement) => {\n removeAnimation(element);\n addAnimation(element);\n };\n\n /** 監聽元素變化 */\n const handleMutation: MutationCallback = (mutations) => {\n const removedElements = new Set<HTMLElement>();\n const addedElements = new Set<HTMLElement>();\n const updatedElements = new Set<HTMLElement>();\n\n for (const mutation of mutations) {\n const { type, target, addedNodes, removedNodes, attributeName } =\n mutation;\n\n if (type === \"attributes\" && target instanceof HTMLElement) {\n // 沒有指定 'data-aos' 就不處理相關邏輯\n if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;\n updatedElements.add(target);\n\n // 會影響觸發點的才開啟刷新\n if (\n attributeName === \"data-aos-anchor-placement\" ||\n attributeName === \"data-aos-offset\"\n ) {\n shouldRefreshRef.current = true;\n }\n } else if (type === \"childList\") {\n collectElements(addedNodes, addedElements);\n collectElements(removedNodes, removedElements);\n }\n }\n\n // 移除 => 新增 => 更新\n for (const element of removedElements) removeAnimation(element);\n for (const element of addedElements) addAnimation(element);\n for (const element of updatedElements) updateAnimation(element);\n\n if (addedElements.size > 0 || removedElements.size > 0) {\n shouldRefreshRef.current = true;\n }\n };\n\n /**\n * ScrollTrigger 刷新\n *\n * > `ScrollTrigger.refresh()` 會導致無限觸發滾動事件、攔截 `window.scroll`\n *\n * > MutationObserver 變化後才會重新開啟避免無限刷新\n * */\n const updateScrollTrigger = () => {\n if (!shouldRefreshRef.current || rafIdRef.current) return;\n\n rafIdRef.current = requestAnimationFrame(() => {\n ScrollTrigger.refresh();\n shouldRefreshRef.current = false;\n rafIdRef.current = 0;\n });\n };\n\n // 初始化\n for (const element of gsap.utils.toArray<HTMLElement>(\n AOS_SELECTORS,\n containerRef.current,\n )) {\n addAnimation(element);\n }\n\n window.addEventListener(\"scroll\", updateScrollTrigger, { passive: true });\n observerRef.current = new MutationObserver(handleMutation);\n observerRef.current.observe(containerRef.current, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: AOS_ATTRIBUTE_KEYS,\n });\n\n return () => {\n window.removeEventListener(\"scroll\", updateScrollTrigger);\n\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n };\n },\n { scope: containerRef, dependencies: [] },\n );\n\n return { containerRef };\n}\n\n/** 搜尋 [data-aos] 變動元素 */\nfunction collectElements(nodes: NodeList, result: Set<HTMLElement>) {\n for (const node of nodes) {\n if (!(node instanceof HTMLElement)) continue;\n\n if (node.hasAttribute(AOS_QUALIFIED_NAME)) {\n result.add(node);\n }\n\n for (const element of node.querySelectorAll<HTMLElement>(AOS_SELECTORS)) {\n result.add(element);\n }\n }\n}\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"../constants\";\n\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\n/** AOS 屬性對應 */\nconst AOS_ATTRIBUTE_MAP = {\n \"data-aos-offset\": \"offset\",\n \"data-aos-delay\": \"delay\",\n \"data-aos-duration\": \"duration\",\n \"data-aos-easing\": \"easing\",\n \"data-aos-mirror\": \"mirror\",\n \"data-aos-once\": \"once\",\n \"data-aos-anchor-placement\": \"anchorPlacement\",\n} satisfies Record<AOSAttributeKey, keyof AnimationOptions>;\n\n/** 解析動畫屬性 */\nexport default function parseAttributes<E extends Element>(element: E) {\n const options = {} as Partial<AnimationOptions>;\n\n for (const key of Object.keys(AOS_ATTRIBUTE_MAP)) {\n const value = element.getAttribute(key);\n\n if (value) {\n const prop = AOS_ATTRIBUTE_MAP[key as AOSAttributeKey];\n\n switch (prop) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n const numberValue = parseNumber(value);\n if (Number.isInteger(numberValue)) {\n options[prop] = numberValue;\n }\n break;\n case \"once\":\n case \"mirror\": {\n const booleanValue = parseBoolean(value);\n if (typeof booleanValue === \"boolean\") {\n options[prop] = booleanValue;\n }\n break;\n }\n case \"easing\":\n const easing = parseEnum(easings, value);\n if (easing) {\n options[prop] = easing;\n }\n break;\n case \"anchorPlacement\": {\n const anchorPlacement = parseEnum(anchorPlacements, value);\n if (anchorPlacement) {\n options[prop] = anchorPlacement;\n }\n break;\n }\n }\n }\n }\n\n return options;\n}\n\nfunction parseEnum<T extends string>(\n list: readonly T[],\n value: string,\n): T | undefined {\n return list.includes(value as T) ? (value as T) : undefined;\n}\n\nfunction parseBoolean(value: string) {\n switch (value) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return undefined;\n }\n}\n\nfunction parseNumber(value: string) {\n const num = Number(value);\n return Number.isInteger(num) ? num : undefined;\n}\n","import gsap from \"gsap\";\n\nimport mergeOptions from \"./utils/mergeOptions\";\nimport definitions, {\n AnimationDefinitions,\n AnimationPreset,\n} from \"./definitions\";\n\nimport type { AnchorPlacement, AnimationOptions } from \"@/types\";\n\nexport type CreateAnimationFunction = (\n element: HTMLElement,\n options?: Partial<AnimationOptions>,\n) => gsap.core.Tween;\n\n/** 解析 ScrollTrigger 的 `start` */\nfunction resolveScrollTriggerStart(\n anchorPlacement: AnchorPlacement,\n offset: number,\n): string {\n const [v1, v2] = anchorPlacement.split(\"-\");\n const anchor = `${v1} ${v2}`;\n\n if (offset === 0 || !Number.isFinite(offset)) return anchor;\n\n const fix = `${offset > 0 ? \"-\" : \"+\"}=${Math.abs(offset)}`;\n return `${anchor}${fix}`;\n}\n\n/** 解析 ScrollTrigger 的 `toggleActions` */\nfunction resolveToggleActions(once?: boolean, mirror?: boolean): string {\n if (once) return \"play none none none\";\n if (mirror) return \"play reverse play reverse\";\n return \"play none none reverse\";\n}\n\n/** 毫秒單位 */\nconst UNIT_MS = 1000;\n\n/** 建立 ScrollTrigger 動畫 */\nfunction createScrollTriggerTween(\n element: HTMLElement,\n preset: AnimationPreset,\n vars: AnimationPreset,\n options?: Partial<AnimationOptions>,\n) {\n const { from, to } = vars;\n const { parentElement } = element;\n const { offset, delay, duration, easing, once, mirror, anchorPlacement } =\n mergeOptions(options);\n\n return gsap.fromTo(\n element,\n {\n ...preset.from,\n ...from,\n },\n {\n ...preset.to,\n ...to,\n ease: easing,\n duration: duration / UNIT_MS,\n delay: delay / UNIT_MS,\n overwrite: \"auto\",\n scrollTrigger: {\n // markers: true,\n invalidateOnRefresh: true,\n // 優先使用上一層被標記的動畫容器\n trigger: parentElement?.hasAttribute(\"data-aos-container\")\n ? parentElement\n : element,\n toggleActions: resolveToggleActions(once, mirror),\n start: resolveScrollTriggerStart(anchorPlacement, offset),\n },\n },\n );\n}\n\n/** 建立動畫物件組 */\nfunction createAnimationMap<T extends Record<string, AnimationDefinitions>>(\n definitions: T,\n): { [K in keyof T]: CreateAnimationFunction } {\n const result = {} as Record<keyof T, CreateAnimationFunction>;\n const keys = Object.keys(definitions) as Array<keyof T>;\n\n for (const key of keys) {\n const { preset, vars } = definitions[key];\n\n result[key] = (element, options) =>\n createScrollTriggerTween(element, preset, vars, options);\n }\n\n return result;\n}\n\nconst animations = createAnimationMap(definitions);\n\nexport default animations;\n","import { anchorPlacements, DEFAULT_OPTIONS, easings } from \"../constants\";\n\nimport type { AnimationOptions } from \"@/types\";\n\n/** 跟預設值合併動畫選項 */\nexport default function mergeOptions(\n ...array: (Partial<AnimationOptions> | undefined | null)[]\n): AnimationOptions {\n const result = { ...DEFAULT_OPTIONS };\n\n for (const options of array) {\n if (!options) continue;\n\n for (const key of Object.keys(options) as (keyof AnimationOptions)[]) {\n const value = options[key];\n\n switch (key) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n if (typeof value === \"number\" && Number.isInteger(value)) {\n result[key] = value;\n }\n break;\n case \"once\":\n case \"mirror\":\n if (typeof value === \"boolean\") {\n result[key] = value;\n }\n break;\n case \"easing\":\n if (verifyEnum(easings, value)) {\n result[key] = value;\n }\n break;\n case \"anchorPlacement\":\n if (verifyEnum(anchorPlacements, value)) {\n result[key] = value;\n }\n break;\n default:\n break;\n }\n }\n }\n\n return result;\n}\n\nfunction verifyEnum<T>(list: readonly T[], value: unknown): value is T {\n return list.includes(value as T);\n}\n","export function translate3d(x: number | string, y: number | string, z: number) {\n return { x, y, z } satisfies gsap.TweenVars;\n}\n\nexport function rotateY(y: number | string) {\n return { rotateY: y } satisfies gsap.TweenVars;\n}\n\nexport function rotateX(x: number | string) {\n return { rotateX: x } satisfies gsap.TweenVars;\n}\n\nexport function scale(x: number, y?: number) {\n return typeof y === \"number\"\n ? ({\n scaleX: x,\n scaleY: y,\n } satisfies gsap.TweenVars)\n : ({\n scale: x,\n } satisfies gsap.TweenVars);\n}\n\n/** @see https://gsap.com/docs/v3/GSAP/CorePlugins/CSS/#3d-transforms */\nexport function perspective(value: number) {\n return {\n transformPerspective: value,\n } satisfies gsap.TweenVars;\n}\n","import {\n perspective,\n rotateX,\n rotateY,\n scale,\n translate3d,\n} from \"./utils/createTweenVars\";\n\n/** 動畫配置 */\nexport interface AnimationPreset {\n /** 動畫起點 */\n from: gsap.TweenVars;\n /** 動畫終點 */\n to: gsap.TweenVars;\n}\n\n/** 動畫定義 */\nexport interface AnimationDefinitions {\n /** 預設配置 */\n preset: AnimationPreset;\n /** 自訂配置 */\n vars: AnimationPreset;\n}\n\n/** 距離 `px` */\nexport const DISTANCE = 100;\n\n/** 動畫預設配置 */\nconst presets = {\n fade: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n transform: \"none\",\n },\n },\n zoom: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n ...translate3d(0, 0, 0),\n ...scale(1),\n },\n },\n slide: {\n from: {\n visibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {\n visibility: \"visible\",\n ...translate3d(0, 0, 0),\n },\n },\n flip: {\n from: {\n backfaceVisibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {},\n },\n} satisfies Record<string, AnimationPreset>;\n\n/** 動畫定義 */\nconst definitions = {\n fade: {\n preset: presets.fade,\n vars: {\n from: {},\n to: {},\n },\n },\n fadeUp: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, DISTANCE, 0),\n to: {},\n },\n },\n fadeDown: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, -DISTANCE, 0),\n to: {},\n },\n },\n fadeLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeUpRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeUpLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeDownRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n fadeDownLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n flipUp: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipDown: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipLeft: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n flipRight: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n slideUp: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"100%\", 0),\n to: {},\n },\n },\n slideDown: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"-100%\", 0),\n to: {},\n },\n },\n slideLeft: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"100%\", 0, 0),\n to: {},\n },\n },\n slideRight: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"-100%\", 0, 0),\n to: {},\n },\n },\n zoomIn: { preset: presets.zoom, vars: { from: scale(0.6), to: {} } },\n zoomInUp: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInDown: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, -DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInLeft: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInRight: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(-DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomOut: { preset: presets.zoom, vars: { from: scale(1.2), to: {} } },\n zoomOutUp: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutDown: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, -DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutLeft: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutRight: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(-DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n} satisfies Record<string, AnimationDefinitions>;\n\nexport default definitions;\n","import parseAttributes from \"./utils/parseAttributes\";\nimport animations, { type CreateAnimationFunction } from \"./animations\";\n\nimport type { Animation, AnimationOptions } from \"@/types\";\n\nconst ANIMATION_REGISTRY: Record<Animation, CreateAnimationFunction> = {\n fade: animations.fade,\n \"fade-up\": animations.fadeUp,\n \"fade-down\": animations.fadeDown,\n \"fade-left\": animations.fadeLeft,\n \"fade-right\": animations.fadeRight,\n \"fade-up-right\": animations.fadeUpRight,\n \"fade-up-left\": animations.fadeUpLeft,\n \"fade-down-right\": animations.fadeDownRight,\n \"fade-down-left\": animations.fadeDownLeft,\n \"flip-up\": animations.flipUp,\n \"flip-down\": animations.flipDown,\n \"flip-left\": animations.flipLeft,\n \"flip-right\": animations.flipRight,\n \"slide-up\": animations.slideUp,\n \"slide-down\": animations.slideDown,\n \"slide-left\": animations.slideLeft,\n \"slide-right\": animations.slideRight,\n \"zoom-in\": animations.zoomIn,\n \"zoom-in-up\": animations.zoomInUp,\n \"zoom-in-down\": animations.zoomInDown,\n \"zoom-in-left\": animations.zoomInLeft,\n \"zoom-in-right\": animations.zoomInRight,\n \"zoom-out\": animations.zoomOut,\n \"zoom-out-up\": animations.zoomOutUp,\n \"zoom-out-down\": animations.zoomOutDown,\n \"zoom-out-left\": animations.zoomOutLeft,\n \"zoom-out-right\": animations.zoomOutRight,\n};\n\n/** 建立動畫元素 */\nexport default function createAnimation<E extends HTMLElement>(\n element: E,\n options?: Partial<AnimationOptions>,\n) {\n const animate = element.getAttribute(\"data-aos\") as Animation | null;\n if (!animate) return;\n\n const handleAnimation = ANIMATION_REGISTRY[animate];\n if (!handleAnimation) return;\n\n return handleAnimation(element, {\n ...options,\n ...parseAttributes(element),\n });\n}\n","/** 區塊元素標籤 */\nexport type BlockElementTag =\n | \"address\"\n | \"article\"\n | \"aside\"\n | \"blockquote\"\n | \"canvas\"\n | \"dd\"\n | \"div\"\n | \"dl\"\n | \"dt\"\n | \"fieldset\"\n | \"figcaption\"\n | \"figure\"\n | \"footer\"\n | \"form\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"header\"\n | \"hr\"\n | \"li\"\n | \"main\"\n | \"nav\"\n | \"noscript\"\n | \"ol\"\n | \"p\"\n | \"pre\"\n | \"section\"\n | \"table\"\n | \"tfoot\"\n | \"ul\"\n | \"video\";\n\n/** 區塊元素標籤清單 */\nconst BLOCK_ELEMENT_TAGS: BlockElementTag[] = [\n \"address\",\n \"article\",\n \"aside\",\n \"blockquote\",\n \"canvas\",\n \"dd\",\n \"div\",\n \"dl\",\n \"dt\",\n \"fieldset\",\n \"figcaption\",\n \"figure\",\n \"footer\",\n \"form\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"header\",\n \"hr\",\n \"li\",\n \"main\",\n \"nav\",\n \"noscript\",\n \"ol\",\n \"p\",\n \"pre\",\n \"section\",\n \"table\",\n \"tfoot\",\n \"ul\",\n \"video\",\n];\n\n/**\n * 檢查標籤是否是區塊元素\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n * */\nexport default function isBlockElementTag(\n value: unknown,\n): value is BlockElementTag {\n return BLOCK_ELEMENT_TAGS.includes(value as BlockElementTag);\n}\n"],"mappings":"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","names":["import_react","import_react","import_gsap","gsap","definitions","gsap"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/components/AOSProvider.tsx","../src/hooks/useAOSScope.ts","../src/animation/constants.ts","../src/animation/utils/parseAttributes.ts","../src/animation/animations.ts","../src/animation/utils/mergeOptions.ts","../src/animation/utils/createTweenVars.ts","../src/animation/definitions.ts","../src/animation/createAnimation.ts","../src/utils/isBlockElementTag.ts"],"sourcesContent":["\"use client\";\n\nexport { default as AOSProvider } from \"./components/AOSProvider\";\nexport { default as useAOSScope } from \"./hooks/useAOSScope\";\n","\"use client\";\n\nimport { type ComponentPropsWithoutRef, createElement } from \"react\";\n\nimport useAOSScope, { type UseAOSScopeOptions } from \"@/hooks/useAOSScope\";\nimport isBlockElementTag, {\n type BlockElementTag,\n} from \"@/utils/isBlockElementTag\";\n\ntype AOSProviderProps<T extends BlockElementTag> = {\n /**\n * 要渲染的 HTML 元素標籤。\n *\n * 如果未提供或非區塊元素,預設會渲染 `<div>`。\n *\n * @default \"div\"\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n */\n component?: T;\n /**\n * 讓子元素繼承的預設動畫參數\n *\n * > 注意:預設選項只作用於後續生成的動畫,這是刻意設計的行為。\n */\n options?: UseAOSScopeOptions;\n} & ComponentPropsWithoutRef<T>;\n\n/**\n * 為子元素提供自動 AOS 動畫能力。\n *\n * 所有帶有 `data-aos` 屬性的子元素都會自動生成動畫。\n */\nexport default function AOSProvider<T extends BlockElementTag = \"div\">({\n component,\n options,\n children,\n ...props\n}: AOSProviderProps<T>) {\n const { containerRef } = useAOSScope(options);\n\n return createElement(\n isBlockElementTag(component) ? component : \"div\",\n { ...props, ref: containerRef },\n children,\n );\n}\n","import { useLayoutEffect, useRef } from \"react\";\nimport { useGSAP } from \"@gsap/react\";\nimport gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\nimport createAnimation from \"@/animation/createAnimation\";\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ngsap.registerPlugin(useGSAP, ScrollTrigger);\n\nexport type UseAOSScopeOptions = Partial<AnimationOptions>;\n\n/** AOS 屬性 */\nconst AOS_ATTRIBUTE_KEYS: (AOSAttributeKey | \"data-aos\")[] = [\n \"data-aos\",\n \"data-aos-offset\",\n \"data-aos-delay\",\n \"data-aos-duration\",\n \"data-aos-easing\",\n \"data-aos-mirror\",\n \"data-aos-once\",\n \"data-aos-anchor-placement\",\n \"data-aos-markers\",\n];\n/** AOS 屬性名稱 */\nconst AOS_QUALIFIED_NAME = \"data-aos\";\n/** AOS 選擇器 */\nconst AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;\n\n/**\n * 綁定 AOS 動畫範圍\n * \n * @example\n * ```tsx\n \"use client\";\n\n import {useAOSScope} from '@/aos';\n \n export default function Demo() {\n const {containerRef} = useAOSScope<HTMLDivElement>()\n return (\n <div ref={containerRef} className=\"overflow-hidden\">\n <div data-aos-container>\n <div data-aos=\"fade-up\">Hello AOS</div>\n </div>\n </div>\n )\n }\n * ```\n */\nexport default function useAOSScope<E extends HTMLElement = HTMLElement>(\n /** 預設動畫選項 */\n options?: UseAOSScopeOptions,\n) {\n const containerRef = useRef<E | null>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n /** 記錄每個元素對應的動畫實例 */\n const elementAnimationsRef = useRef<WeakMap<HTMLElement, gsap.core.Tween>>(\n new WeakMap(),\n );\n const currentOptionsRef = useRef(options);\n const rafIdRef = useRef<number>(0);\n const shouldRefreshRef = useRef(false);\n\n // 下次新增動畫才會套用覆蓋預設值\n useLayoutEffect(() => {\n currentOptionsRef.current = options;\n }, [options]);\n\n useGSAP(\n (_, contextSafe) => {\n if (!containerRef.current || !contextSafe) return;\n\n /** 新增動畫 */\n const addAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n if (elementAnimations.has(element)) return;\n\n const newAnimation = contextSafe(createAnimation)(\n element,\n currentOptionsRef.current,\n );\n if (!newAnimation) return;\n\n elementAnimations.set(element, newAnimation);\n };\n\n /** 移除動畫 */\n const removeAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n const animation = elementAnimations.get(element);\n if (!animation) return;\n\n animation.revert();\n elementAnimations.delete(element);\n };\n\n /** 更新動畫 */\n const updateAnimation = (element: HTMLElement) => {\n removeAnimation(element);\n addAnimation(element);\n };\n\n /** 監聽元素變化 */\n const handleMutation: MutationCallback = (mutations) => {\n const removedElements = new Set<HTMLElement>();\n const addedElements = new Set<HTMLElement>();\n const updatedElements = new Set<HTMLElement>();\n\n for (const mutation of mutations) {\n const { type, target, addedNodes, removedNodes } = mutation;\n\n if (type === \"attributes\" && target instanceof HTMLElement) {\n // 沒有指定 'data-aos' 就不處理相關邏輯\n if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;\n updatedElements.add(target);\n } else if (type === \"childList\") {\n collectElements(addedNodes, addedElements);\n collectElements(removedNodes, removedElements);\n }\n }\n\n // 移除 => 新增 => 更新\n for (const element of removedElements) removeAnimation(element);\n for (const element of addedElements) addAnimation(element);\n for (const element of updatedElements) updateAnimation(element);\n\n if (addedElements.size > 0 || removedElements.size > 0) {\n shouldRefreshRef.current = true;\n }\n };\n\n /**\n * ScrollTrigger 刷新\n *\n * > `ScrollTrigger.refresh()` 會導致無限觸發滾動事件、攔截 `window.scroll`\n *\n * > MutationObserver 變化後才會重新開啟避免無限刷新\n * */\n const updateScrollTrigger = () => {\n if (!shouldRefreshRef.current || rafIdRef.current) return;\n\n rafIdRef.current = requestAnimationFrame(() => {\n ScrollTrigger.refresh();\n shouldRefreshRef.current = false;\n rafIdRef.current = 0;\n });\n };\n\n // 初始化\n for (const element of gsap.utils.toArray<HTMLElement>(\n AOS_SELECTORS,\n containerRef.current,\n )) {\n addAnimation(element);\n }\n\n window.addEventListener(\"scroll\", updateScrollTrigger, { passive: true });\n observerRef.current = new MutationObserver(handleMutation);\n observerRef.current.observe(containerRef.current, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: AOS_ATTRIBUTE_KEYS,\n });\n\n return () => {\n window.removeEventListener(\"scroll\", updateScrollTrigger);\n\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n };\n },\n { scope: containerRef, dependencies: [] },\n );\n\n return { containerRef };\n}\n\n/** 搜尋 [data-aos] 變動元素 */\nfunction collectElements(nodes: NodeList, result: Set<HTMLElement>) {\n for (const node of nodes) {\n if (!(node instanceof HTMLElement)) continue;\n\n if (node.hasAttribute(AOS_QUALIFIED_NAME)) {\n result.add(node);\n }\n\n for (const element of node.querySelectorAll<HTMLElement>(AOS_SELECTORS)) {\n result.add(element);\n }\n }\n}\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n markers: false,\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"../constants\";\n\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\n/** AOS 屬性對應 */\nconst AOS_ATTRIBUTE_MAP = {\n \"data-aos-offset\": \"offset\",\n \"data-aos-delay\": \"delay\",\n \"data-aos-duration\": \"duration\",\n \"data-aos-easing\": \"easing\",\n \"data-aos-mirror\": \"mirror\",\n \"data-aos-once\": \"once\",\n \"data-aos-anchor-placement\": \"anchorPlacement\",\n \"data-aos-markers\": \"markers\",\n} satisfies Record<AOSAttributeKey, keyof AnimationOptions>;\n\n/** 解析動畫屬性 */\nexport default function parseAttributes<E extends Element>(element: E) {\n const options = {} as Partial<AnimationOptions>;\n\n for (const key of Object.keys(AOS_ATTRIBUTE_MAP)) {\n const value = element.getAttribute(key);\n\n if (value) {\n const prop = AOS_ATTRIBUTE_MAP[key as AOSAttributeKey];\n\n switch (prop) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n const numberValue = parseNumber(value);\n if (Number.isInteger(numberValue)) {\n options[prop] = numberValue;\n }\n break;\n case \"once\":\n case \"mirror\":\n case \"markers\":\n const booleanValue = parseBoolean(value);\n if (typeof booleanValue === \"boolean\") {\n options[prop] = booleanValue;\n }\n break;\n case \"easing\":\n const easing = parseEnum(easings, value);\n if (easing) {\n options[prop] = easing;\n }\n break;\n case \"anchorPlacement\":\n const anchorPlacement = parseEnum(anchorPlacements, value);\n if (anchorPlacement) {\n options[prop] = anchorPlacement;\n }\n break;\n }\n }\n }\n\n return options;\n}\n\nfunction parseEnum<T extends string>(\n list: readonly T[],\n value: string,\n): T | undefined {\n return list.includes(value as T) ? (value as T) : undefined;\n}\n\nfunction parseBoolean(value: string) {\n switch (value) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return undefined;\n }\n}\n\nfunction parseNumber(value: string) {\n const num = Number(value);\n return Number.isInteger(num) ? num : undefined;\n}\n","import gsap from \"gsap\";\n\nimport mergeOptions from \"./utils/mergeOptions\";\nimport definitions, {\n AnimationDefinitions,\n AnimationPreset,\n} from \"./definitions\";\n\nimport type { AnchorPlacement, AnimationOptions } from \"@/types\";\n\nexport type CreateAnimationFunction = (\n element: HTMLElement,\n options?: Partial<AnimationOptions>,\n) => gsap.core.Tween;\n\n/** 解析 ScrollTrigger 的 `start` */\nfunction resolveScrollTriggerStart(\n anchorPlacement: AnchorPlacement,\n offset: number,\n): string {\n const [v1, v2] = anchorPlacement.split(\"-\");\n const anchor = `${v1} ${v2}`;\n\n if (offset === 0 || !Number.isFinite(offset)) return anchor;\n\n const fix = `${offset > 0 ? \"-\" : \"+\"}=${Math.abs(offset)}`;\n return `${anchor}${fix}`;\n}\n\n/** 解析 ScrollTrigger 的 `toggleActions` */\nfunction resolveToggleActions(once?: boolean, mirror?: boolean): string {\n if (once) return \"play none none none\";\n if (mirror) return \"play reverse play reverse\";\n return \"play none none reverse\";\n}\n\n/** 毫秒單位 */\nconst UNIT_MS = 1000;\n\n/** 建立 ScrollTrigger 動畫 */\nfunction createScrollTriggerTween(\n element: HTMLElement,\n preset: AnimationPreset,\n vars: AnimationPreset,\n options?: Partial<AnimationOptions>,\n) {\n const { from, to } = vars;\n const { parentElement } = element;\n const {\n offset,\n delay,\n duration,\n easing,\n once,\n mirror,\n anchorPlacement,\n markers,\n } = mergeOptions(options);\n\n return gsap.fromTo(\n element,\n {\n ...preset.from,\n ...from,\n },\n {\n ...preset.to,\n ...to,\n ease: easing,\n duration: duration / UNIT_MS,\n delay: delay / UNIT_MS,\n overwrite: \"auto\",\n scrollTrigger: {\n markers,\n invalidateOnRefresh: true,\n // 優先使用上一層被標記的動畫容器\n trigger: parentElement?.hasAttribute(\"data-aos-container\")\n ? parentElement\n : element,\n toggleActions: resolveToggleActions(once, mirror),\n start: resolveScrollTriggerStart(anchorPlacement, offset),\n },\n },\n );\n}\n\n/** 建立動畫物件組 */\nfunction createAnimationMap<T extends Record<string, AnimationDefinitions>>(\n definitions: T,\n): { [K in keyof T]: CreateAnimationFunction } {\n const result = {} as Record<keyof T, CreateAnimationFunction>;\n const keys = Object.keys(definitions) as Array<keyof T>;\n\n for (const key of keys) {\n const { preset, vars } = definitions[key];\n\n result[key] = (element, options) =>\n createScrollTriggerTween(element, preset, vars, options);\n }\n\n return result;\n}\n\nconst animations = createAnimationMap(definitions);\n\nexport default animations;\n","import { anchorPlacements, DEFAULT_OPTIONS, easings } from \"../constants\";\n\nimport type { AnimationOptions } from \"@/types\";\n\n/** 跟預設值合併動畫選項 */\nexport default function mergeOptions(\n ...array: (Partial<AnimationOptions> | undefined | null)[]\n): AnimationOptions {\n const result = { ...DEFAULT_OPTIONS };\n\n for (const options of array) {\n if (!options) continue;\n\n for (const key of Object.keys(options) as (keyof AnimationOptions)[]) {\n const value = options[key];\n\n switch (key) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n if (typeof value === \"number\" && Number.isInteger(value)) {\n result[key] = value;\n }\n break;\n case \"once\":\n case \"mirror\":\n case \"markers\":\n if (typeof value === \"boolean\") {\n result[key] = value;\n }\n break;\n case \"easing\":\n if (verifyEnum(easings, value)) {\n result[key] = value;\n }\n break;\n case \"anchorPlacement\":\n if (verifyEnum(anchorPlacements, value)) {\n result[key] = value;\n }\n break;\n default:\n break;\n }\n }\n }\n\n return result;\n}\n\nfunction verifyEnum<T>(list: readonly T[], value: unknown): value is T {\n return list.includes(value as T);\n}\n","export function translate3d(x: number | string, y: number | string, z: number) {\n return { x, y, z } satisfies gsap.TweenVars;\n}\n\nexport function rotateY(y: number | string) {\n return { rotateY: y } satisfies gsap.TweenVars;\n}\n\nexport function rotateX(x: number | string) {\n return { rotateX: x } satisfies gsap.TweenVars;\n}\n\nexport function scale(x: number, y?: number) {\n return typeof y === \"number\"\n ? ({\n scaleX: x,\n scaleY: y,\n } satisfies gsap.TweenVars)\n : ({\n scale: x,\n } satisfies gsap.TweenVars);\n}\n\n/** @see https://gsap.com/docs/v3/GSAP/CorePlugins/CSS/#3d-transforms */\nexport function perspective(value: number) {\n return {\n transformPerspective: value,\n } satisfies gsap.TweenVars;\n}\n","import {\n perspective,\n rotateX,\n rotateY,\n scale,\n translate3d,\n} from \"./utils/createTweenVars\";\n\n/** 動畫配置 */\nexport interface AnimationPreset {\n /** 動畫起點 */\n from: gsap.TweenVars;\n /** 動畫終點 */\n to: gsap.TweenVars;\n}\n\n/** 動畫定義 */\nexport interface AnimationDefinitions {\n /** 預設配置 */\n preset: AnimationPreset;\n /** 自訂配置 */\n vars: AnimationPreset;\n}\n\n/** 距離 `px` */\nexport const DISTANCE = 100;\n\n/** 動畫預設配置 */\nconst presets = {\n fade: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n transform: \"none\",\n },\n },\n zoom: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n ...translate3d(0, 0, 0),\n ...scale(1),\n },\n },\n slide: {\n from: {\n visibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {\n visibility: \"visible\",\n ...translate3d(0, 0, 0),\n },\n },\n flip: {\n from: {\n backfaceVisibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {},\n },\n} satisfies Record<string, AnimationPreset>;\n\n/** 動畫定義 */\nconst definitions = {\n fade: {\n preset: presets.fade,\n vars: {\n from: {},\n to: {},\n },\n },\n fadeUp: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, DISTANCE, 0),\n to: {},\n },\n },\n fadeDown: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, -DISTANCE, 0),\n to: {},\n },\n },\n fadeLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeUpRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeUpLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeDownRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n fadeDownLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n flipUp: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipDown: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipLeft: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n flipRight: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n slideUp: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"100%\", 0),\n to: {},\n },\n },\n slideDown: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"-100%\", 0),\n to: {},\n },\n },\n slideLeft: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"100%\", 0, 0),\n to: {},\n },\n },\n slideRight: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"-100%\", 0, 0),\n to: {},\n },\n },\n zoomIn: { preset: presets.zoom, vars: { from: scale(0.6), to: {} } },\n zoomInUp: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInDown: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, -DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInLeft: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInRight: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(-DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomOut: { preset: presets.zoom, vars: { from: scale(1.2), to: {} } },\n zoomOutUp: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutDown: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, -DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutLeft: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutRight: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(-DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n} satisfies Record<string, AnimationDefinitions>;\n\nexport default definitions;\n","import parseAttributes from \"./utils/parseAttributes\";\nimport animations, { type CreateAnimationFunction } from \"./animations\";\n\nimport type { Animation, AnimationOptions } from \"@/types\";\n\nconst ANIMATION_REGISTRY: Record<Animation, CreateAnimationFunction> = {\n fade: animations.fade,\n \"fade-up\": animations.fadeUp,\n \"fade-down\": animations.fadeDown,\n \"fade-left\": animations.fadeLeft,\n \"fade-right\": animations.fadeRight,\n \"fade-up-right\": animations.fadeUpRight,\n \"fade-up-left\": animations.fadeUpLeft,\n \"fade-down-right\": animations.fadeDownRight,\n \"fade-down-left\": animations.fadeDownLeft,\n \"flip-up\": animations.flipUp,\n \"flip-down\": animations.flipDown,\n \"flip-left\": animations.flipLeft,\n \"flip-right\": animations.flipRight,\n \"slide-up\": animations.slideUp,\n \"slide-down\": animations.slideDown,\n \"slide-left\": animations.slideLeft,\n \"slide-right\": animations.slideRight,\n \"zoom-in\": animations.zoomIn,\n \"zoom-in-up\": animations.zoomInUp,\n \"zoom-in-down\": animations.zoomInDown,\n \"zoom-in-left\": animations.zoomInLeft,\n \"zoom-in-right\": animations.zoomInRight,\n \"zoom-out\": animations.zoomOut,\n \"zoom-out-up\": animations.zoomOutUp,\n \"zoom-out-down\": animations.zoomOutDown,\n \"zoom-out-left\": animations.zoomOutLeft,\n \"zoom-out-right\": animations.zoomOutRight,\n};\n\n/** 建立動畫元素 */\nexport default function createAnimation<E extends HTMLElement>(\n element: E,\n options?: Partial<AnimationOptions>,\n) {\n const animate = element.getAttribute(\"data-aos\") as Animation | null;\n if (!animate) return;\n\n const handleAnimation = ANIMATION_REGISTRY[animate];\n if (!handleAnimation) return;\n\n return handleAnimation(element, {\n ...options,\n ...parseAttributes(element),\n });\n}\n","/** 區塊元素標籤 */\nexport type BlockElementTag =\n | \"address\"\n | \"article\"\n | \"aside\"\n | \"blockquote\"\n | \"canvas\"\n | \"dd\"\n | \"div\"\n | \"dl\"\n | \"dt\"\n | \"fieldset\"\n | \"figcaption\"\n | \"figure\"\n | \"footer\"\n | \"form\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"header\"\n | \"hr\"\n | \"li\"\n | \"main\"\n | \"nav\"\n | \"noscript\"\n | \"ol\"\n | \"p\"\n | \"pre\"\n | \"section\"\n | \"table\"\n | \"tfoot\"\n | \"ul\"\n | \"video\";\n\n/** 區塊元素標籤清單 */\nconst BLOCK_ELEMENT_TAGS: BlockElementTag[] = [\n \"address\",\n \"article\",\n \"aside\",\n \"blockquote\",\n \"canvas\",\n \"dd\",\n \"div\",\n \"dl\",\n \"dt\",\n \"fieldset\",\n \"figcaption\",\n \"figure\",\n \"footer\",\n \"form\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"header\",\n \"hr\",\n \"li\",\n \"main\",\n \"nav\",\n \"noscript\",\n \"ol\",\n \"p\",\n \"pre\",\n \"section\",\n \"table\",\n \"tfoot\",\n \"ul\",\n \"video\",\n];\n\n/**\n * 檢查標籤是否是區塊元素\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n * */\nexport default function isBlockElementTag(\n value: unknown,\n): value is BlockElementTag {\n return BLOCK_ELEMENT_TAGS.includes(value as BlockElementTag);\n}\n"],"mappings":"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","names":["import_react","import_react","import_gsap","gsap","definitions","gsap"]}
package/dist/client.mjs CHANGED
@@ -48,7 +48,8 @@ var DEFAULT_OPTIONS = {
48
48
  easing: "none",
49
49
  once: false,
50
50
  mirror: false,
51
- anchorPlacement: "top-bottom"
51
+ anchorPlacement: "top-bottom",
52
+ markers: false
52
53
  };
53
54
  var easings = [
54
55
  "none",
@@ -113,7 +114,8 @@ var AOS_ATTRIBUTE_MAP = {
113
114
  "data-aos-easing": "easing",
114
115
  "data-aos-mirror": "mirror",
115
116
  "data-aos-once": "once",
116
- "data-aos-anchor-placement": "anchorPlacement"
117
+ "data-aos-anchor-placement": "anchorPlacement",
118
+ "data-aos-markers": "markers"
117
119
  };
118
120
  function parseAttributes(element) {
119
121
  const options = {};
@@ -131,26 +133,25 @@ function parseAttributes(element) {
131
133
  }
132
134
  break;
133
135
  case "once":
134
- case "mirror": {
136
+ case "mirror":
137
+ case "markers":
135
138
  const booleanValue = parseBoolean(value);
136
139
  if (typeof booleanValue === "boolean") {
137
140
  options[prop] = booleanValue;
138
141
  }
139
142
  break;
140
- }
141
143
  case "easing":
142
144
  const easing = parseEnum(easings, value);
143
145
  if (easing) {
144
146
  options[prop] = easing;
145
147
  }
146
148
  break;
147
- case "anchorPlacement": {
149
+ case "anchorPlacement":
148
150
  const anchorPlacement = parseEnum(anchorPlacements, value);
149
151
  if (anchorPlacement) {
150
152
  options[prop] = anchorPlacement;
151
153
  }
152
154
  break;
153
- }
154
155
  }
155
156
  }
156
157
  }
@@ -194,6 +195,7 @@ function mergeOptions(...array) {
194
195
  break;
195
196
  case "once":
196
197
  case "mirror":
198
+ case "markers":
197
199
  if (typeof value === "boolean") {
198
200
  result[key] = value;
199
201
  }
@@ -480,7 +482,16 @@ var UNIT_MS = 1e3;
480
482
  function createScrollTriggerTween(element, preset, vars, options) {
481
483
  const { from, to } = vars;
482
484
  const { parentElement } = element;
483
- const { offset, delay, duration, easing, once, mirror, anchorPlacement } = mergeOptions(options);
485
+ const {
486
+ offset,
487
+ delay,
488
+ duration,
489
+ easing,
490
+ once,
491
+ mirror,
492
+ anchorPlacement,
493
+ markers
494
+ } = mergeOptions(options);
484
495
  return gsap.fromTo(
485
496
  element,
486
497
  __spreadValues(__spreadValues({}, preset.from), from),
@@ -490,7 +501,7 @@ function createScrollTriggerTween(element, preset, vars, options) {
490
501
  delay: delay / UNIT_MS,
491
502
  overwrite: "auto",
492
503
  scrollTrigger: {
493
- // markers: true,
504
+ markers,
494
505
  invalidateOnRefresh: true,
495
506
  // 優先使用上一層被標記的動畫容器
496
507
  trigger: (parentElement == null ? void 0 : parentElement.hasAttribute("data-aos-container")) ? parentElement : element,
@@ -560,7 +571,8 @@ var AOS_ATTRIBUTE_KEYS = [
560
571
  "data-aos-easing",
561
572
  "data-aos-mirror",
562
573
  "data-aos-once",
563
- "data-aos-anchor-placement"
574
+ "data-aos-anchor-placement",
575
+ "data-aos-markers"
564
576
  ];
565
577
  var AOS_QUALIFIED_NAME = "data-aos";
566
578
  var AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;
@@ -605,13 +617,10 @@ function useAOSScope(options) {
605
617
  const addedElements = /* @__PURE__ */ new Set();
606
618
  const updatedElements = /* @__PURE__ */ new Set();
607
619
  for (const mutation of mutations) {
608
- const { type, target, addedNodes, removedNodes, attributeName } = mutation;
620
+ const { type, target, addedNodes, removedNodes } = mutation;
609
621
  if (type === "attributes" && target instanceof HTMLElement) {
610
622
  if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;
611
623
  updatedElements.add(target);
612
- if (attributeName === "data-aos-anchor-placement" || attributeName === "data-aos-offset") {
613
- shouldRefreshRef.current = true;
614
- }
615
624
  } else if (type === "childList") {
616
625
  collectElements(addedNodes, addedElements);
617
626
  collectElements(removedNodes, removedElements);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/AOSProvider.tsx","../src/hooks/useAOSScope.ts","../src/animation/constants.ts","../src/animation/utils/parseAttributes.ts","../src/animation/animations.ts","../src/animation/utils/mergeOptions.ts","../src/animation/utils/createTweenVars.ts","../src/animation/definitions.ts","../src/animation/createAnimation.ts","../src/utils/isBlockElementTag.ts"],"sourcesContent":["\"use client\";\n\nimport { type ComponentPropsWithoutRef, createElement } from \"react\";\n\nimport useAOSScope, { type UseAOSScopeOptions } from \"@/hooks/useAOSScope\";\nimport isBlockElementTag, {\n type BlockElementTag,\n} from \"@/utils/isBlockElementTag\";\n\ntype AOSProviderProps<T extends BlockElementTag> = {\n /**\n * 要渲染的 HTML 元素標籤。\n *\n * 如果未提供或非區塊元素,預設會渲染 `<div>`。\n *\n * @default \"div\"\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n */\n component?: T;\n /**\n * 讓子元素繼承的預設動畫參數\n *\n * > 注意:預設選項只作用於後續生成的動畫,這是刻意設計的行為。\n */\n options?: UseAOSScopeOptions;\n} & ComponentPropsWithoutRef<T>;\n\n/**\n * 為子元素提供自動 AOS 動畫能力。\n *\n * 所有帶有 `data-aos` 屬性的子元素都會自動生成動畫。\n */\nexport default function AOSProvider<T extends BlockElementTag = \"div\">({\n component,\n options,\n children,\n ...props\n}: AOSProviderProps<T>) {\n const { containerRef } = useAOSScope(options);\n\n return createElement(\n isBlockElementTag(component) ? component : \"div\",\n { ...props, ref: containerRef },\n children,\n );\n}\n","import { useLayoutEffect, useRef } from \"react\";\nimport { useGSAP } from \"@gsap/react\";\nimport gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\nimport createAnimation from \"@/animation/createAnimation\";\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ngsap.registerPlugin(useGSAP, ScrollTrigger);\n\nexport type UseAOSScopeOptions = Partial<AnimationOptions>;\n\n/** AOS 屬性 */\nconst AOS_ATTRIBUTE_KEYS: (AOSAttributeKey | \"data-aos\")[] = [\n \"data-aos\",\n \"data-aos-offset\",\n \"data-aos-delay\",\n \"data-aos-duration\",\n \"data-aos-easing\",\n \"data-aos-mirror\",\n \"data-aos-once\",\n \"data-aos-anchor-placement\",\n];\n/** AOS 屬性名稱 */\nconst AOS_QUALIFIED_NAME = \"data-aos\";\n/** AOS 選擇器 */\nconst AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;\n\n/**\n * 綁定 AOS 動畫範圍\n * \n * @example\n * ```tsx\n \"use client\";\n\n import {useAOSScope} from '@/aos';\n \n export default function Demo() {\n const {containerRef} = useAOSScope<HTMLDivElement>()\n return (\n <div ref={containerRef} className=\"overflow-hidden\">\n <div data-aos-container>\n <div data-aos=\"fade-up\">Hello AOS</div>\n </div>\n </div>\n )\n }\n * ```\n */\nexport default function useAOSScope<E extends HTMLElement = HTMLElement>(\n /** 預設動畫選項 */\n options?: UseAOSScopeOptions,\n) {\n const containerRef = useRef<E | null>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n /** 記錄每個元素對應的動畫實例 */\n const elementAnimationsRef = useRef<WeakMap<HTMLElement, gsap.core.Tween>>(\n new WeakMap(),\n );\n const currentOptionsRef = useRef(options);\n const rafIdRef = useRef<number>(0);\n const shouldRefreshRef = useRef(false);\n\n // 下次新增動畫才會套用覆蓋預設值\n useLayoutEffect(() => {\n currentOptionsRef.current = options;\n }, [options]);\n\n useGSAP(\n (_, contextSafe) => {\n if (!containerRef.current || !contextSafe) return;\n\n /** 新增動畫 */\n const addAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n if (elementAnimations.has(element)) return;\n\n const newAnimation = contextSafe(createAnimation)(\n element,\n currentOptionsRef.current,\n );\n if (!newAnimation) return;\n\n elementAnimations.set(element, newAnimation);\n };\n\n /** 移除動畫 */\n const removeAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n const animation = elementAnimations.get(element);\n if (!animation) return;\n\n animation.revert();\n elementAnimations.delete(element);\n };\n\n /** 更新動畫 */\n const updateAnimation = (element: HTMLElement) => {\n removeAnimation(element);\n addAnimation(element);\n };\n\n /** 監聽元素變化 */\n const handleMutation: MutationCallback = (mutations) => {\n const removedElements = new Set<HTMLElement>();\n const addedElements = new Set<HTMLElement>();\n const updatedElements = new Set<HTMLElement>();\n\n for (const mutation of mutations) {\n const { type, target, addedNodes, removedNodes, attributeName } =\n mutation;\n\n if (type === \"attributes\" && target instanceof HTMLElement) {\n // 沒有指定 'data-aos' 就不處理相關邏輯\n if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;\n updatedElements.add(target);\n\n // 會影響觸發點的才開啟刷新\n if (\n attributeName === \"data-aos-anchor-placement\" ||\n attributeName === \"data-aos-offset\"\n ) {\n shouldRefreshRef.current = true;\n }\n } else if (type === \"childList\") {\n collectElements(addedNodes, addedElements);\n collectElements(removedNodes, removedElements);\n }\n }\n\n // 移除 => 新增 => 更新\n for (const element of removedElements) removeAnimation(element);\n for (const element of addedElements) addAnimation(element);\n for (const element of updatedElements) updateAnimation(element);\n\n if (addedElements.size > 0 || removedElements.size > 0) {\n shouldRefreshRef.current = true;\n }\n };\n\n /**\n * ScrollTrigger 刷新\n *\n * > `ScrollTrigger.refresh()` 會導致無限觸發滾動事件、攔截 `window.scroll`\n *\n * > MutationObserver 變化後才會重新開啟避免無限刷新\n * */\n const updateScrollTrigger = () => {\n if (!shouldRefreshRef.current || rafIdRef.current) return;\n\n rafIdRef.current = requestAnimationFrame(() => {\n ScrollTrigger.refresh();\n shouldRefreshRef.current = false;\n rafIdRef.current = 0;\n });\n };\n\n // 初始化\n for (const element of gsap.utils.toArray<HTMLElement>(\n AOS_SELECTORS,\n containerRef.current,\n )) {\n addAnimation(element);\n }\n\n window.addEventListener(\"scroll\", updateScrollTrigger, { passive: true });\n observerRef.current = new MutationObserver(handleMutation);\n observerRef.current.observe(containerRef.current, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: AOS_ATTRIBUTE_KEYS,\n });\n\n return () => {\n window.removeEventListener(\"scroll\", updateScrollTrigger);\n\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n };\n },\n { scope: containerRef, dependencies: [] },\n );\n\n return { containerRef };\n}\n\n/** 搜尋 [data-aos] 變動元素 */\nfunction collectElements(nodes: NodeList, result: Set<HTMLElement>) {\n for (const node of nodes) {\n if (!(node instanceof HTMLElement)) continue;\n\n if (node.hasAttribute(AOS_QUALIFIED_NAME)) {\n result.add(node);\n }\n\n for (const element of node.querySelectorAll<HTMLElement>(AOS_SELECTORS)) {\n result.add(element);\n }\n }\n}\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"../constants\";\n\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\n/** AOS 屬性對應 */\nconst AOS_ATTRIBUTE_MAP = {\n \"data-aos-offset\": \"offset\",\n \"data-aos-delay\": \"delay\",\n \"data-aos-duration\": \"duration\",\n \"data-aos-easing\": \"easing\",\n \"data-aos-mirror\": \"mirror\",\n \"data-aos-once\": \"once\",\n \"data-aos-anchor-placement\": \"anchorPlacement\",\n} satisfies Record<AOSAttributeKey, keyof AnimationOptions>;\n\n/** 解析動畫屬性 */\nexport default function parseAttributes<E extends Element>(element: E) {\n const options = {} as Partial<AnimationOptions>;\n\n for (const key of Object.keys(AOS_ATTRIBUTE_MAP)) {\n const value = element.getAttribute(key);\n\n if (value) {\n const prop = AOS_ATTRIBUTE_MAP[key as AOSAttributeKey];\n\n switch (prop) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n const numberValue = parseNumber(value);\n if (Number.isInteger(numberValue)) {\n options[prop] = numberValue;\n }\n break;\n case \"once\":\n case \"mirror\": {\n const booleanValue = parseBoolean(value);\n if (typeof booleanValue === \"boolean\") {\n options[prop] = booleanValue;\n }\n break;\n }\n case \"easing\":\n const easing = parseEnum(easings, value);\n if (easing) {\n options[prop] = easing;\n }\n break;\n case \"anchorPlacement\": {\n const anchorPlacement = parseEnum(anchorPlacements, value);\n if (anchorPlacement) {\n options[prop] = anchorPlacement;\n }\n break;\n }\n }\n }\n }\n\n return options;\n}\n\nfunction parseEnum<T extends string>(\n list: readonly T[],\n value: string,\n): T | undefined {\n return list.includes(value as T) ? (value as T) : undefined;\n}\n\nfunction parseBoolean(value: string) {\n switch (value) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return undefined;\n }\n}\n\nfunction parseNumber(value: string) {\n const num = Number(value);\n return Number.isInteger(num) ? num : undefined;\n}\n","import gsap from \"gsap\";\n\nimport mergeOptions from \"./utils/mergeOptions\";\nimport definitions, {\n AnimationDefinitions,\n AnimationPreset,\n} from \"./definitions\";\n\nimport type { AnchorPlacement, AnimationOptions } from \"@/types\";\n\nexport type CreateAnimationFunction = (\n element: HTMLElement,\n options?: Partial<AnimationOptions>,\n) => gsap.core.Tween;\n\n/** 解析 ScrollTrigger 的 `start` */\nfunction resolveScrollTriggerStart(\n anchorPlacement: AnchorPlacement,\n offset: number,\n): string {\n const [v1, v2] = anchorPlacement.split(\"-\");\n const anchor = `${v1} ${v2}`;\n\n if (offset === 0 || !Number.isFinite(offset)) return anchor;\n\n const fix = `${offset > 0 ? \"-\" : \"+\"}=${Math.abs(offset)}`;\n return `${anchor}${fix}`;\n}\n\n/** 解析 ScrollTrigger 的 `toggleActions` */\nfunction resolveToggleActions(once?: boolean, mirror?: boolean): string {\n if (once) return \"play none none none\";\n if (mirror) return \"play reverse play reverse\";\n return \"play none none reverse\";\n}\n\n/** 毫秒單位 */\nconst UNIT_MS = 1000;\n\n/** 建立 ScrollTrigger 動畫 */\nfunction createScrollTriggerTween(\n element: HTMLElement,\n preset: AnimationPreset,\n vars: AnimationPreset,\n options?: Partial<AnimationOptions>,\n) {\n const { from, to } = vars;\n const { parentElement } = element;\n const { offset, delay, duration, easing, once, mirror, anchorPlacement } =\n mergeOptions(options);\n\n return gsap.fromTo(\n element,\n {\n ...preset.from,\n ...from,\n },\n {\n ...preset.to,\n ...to,\n ease: easing,\n duration: duration / UNIT_MS,\n delay: delay / UNIT_MS,\n overwrite: \"auto\",\n scrollTrigger: {\n // markers: true,\n invalidateOnRefresh: true,\n // 優先使用上一層被標記的動畫容器\n trigger: parentElement?.hasAttribute(\"data-aos-container\")\n ? parentElement\n : element,\n toggleActions: resolveToggleActions(once, mirror),\n start: resolveScrollTriggerStart(anchorPlacement, offset),\n },\n },\n );\n}\n\n/** 建立動畫物件組 */\nfunction createAnimationMap<T extends Record<string, AnimationDefinitions>>(\n definitions: T,\n): { [K in keyof T]: CreateAnimationFunction } {\n const result = {} as Record<keyof T, CreateAnimationFunction>;\n const keys = Object.keys(definitions) as Array<keyof T>;\n\n for (const key of keys) {\n const { preset, vars } = definitions[key];\n\n result[key] = (element, options) =>\n createScrollTriggerTween(element, preset, vars, options);\n }\n\n return result;\n}\n\nconst animations = createAnimationMap(definitions);\n\nexport default animations;\n","import { anchorPlacements, DEFAULT_OPTIONS, easings } from \"../constants\";\n\nimport type { AnimationOptions } from \"@/types\";\n\n/** 跟預設值合併動畫選項 */\nexport default function mergeOptions(\n ...array: (Partial<AnimationOptions> | undefined | null)[]\n): AnimationOptions {\n const result = { ...DEFAULT_OPTIONS };\n\n for (const options of array) {\n if (!options) continue;\n\n for (const key of Object.keys(options) as (keyof AnimationOptions)[]) {\n const value = options[key];\n\n switch (key) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n if (typeof value === \"number\" && Number.isInteger(value)) {\n result[key] = value;\n }\n break;\n case \"once\":\n case \"mirror\":\n if (typeof value === \"boolean\") {\n result[key] = value;\n }\n break;\n case \"easing\":\n if (verifyEnum(easings, value)) {\n result[key] = value;\n }\n break;\n case \"anchorPlacement\":\n if (verifyEnum(anchorPlacements, value)) {\n result[key] = value;\n }\n break;\n default:\n break;\n }\n }\n }\n\n return result;\n}\n\nfunction verifyEnum<T>(list: readonly T[], value: unknown): value is T {\n return list.includes(value as T);\n}\n","export function translate3d(x: number | string, y: number | string, z: number) {\n return { x, y, z } satisfies gsap.TweenVars;\n}\n\nexport function rotateY(y: number | string) {\n return { rotateY: y } satisfies gsap.TweenVars;\n}\n\nexport function rotateX(x: number | string) {\n return { rotateX: x } satisfies gsap.TweenVars;\n}\n\nexport function scale(x: number, y?: number) {\n return typeof y === \"number\"\n ? ({\n scaleX: x,\n scaleY: y,\n } satisfies gsap.TweenVars)\n : ({\n scale: x,\n } satisfies gsap.TweenVars);\n}\n\n/** @see https://gsap.com/docs/v3/GSAP/CorePlugins/CSS/#3d-transforms */\nexport function perspective(value: number) {\n return {\n transformPerspective: value,\n } satisfies gsap.TweenVars;\n}\n","import {\n perspective,\n rotateX,\n rotateY,\n scale,\n translate3d,\n} from \"./utils/createTweenVars\";\n\n/** 動畫配置 */\nexport interface AnimationPreset {\n /** 動畫起點 */\n from: gsap.TweenVars;\n /** 動畫終點 */\n to: gsap.TweenVars;\n}\n\n/** 動畫定義 */\nexport interface AnimationDefinitions {\n /** 預設配置 */\n preset: AnimationPreset;\n /** 自訂配置 */\n vars: AnimationPreset;\n}\n\n/** 距離 `px` */\nexport const DISTANCE = 100;\n\n/** 動畫預設配置 */\nconst presets = {\n fade: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n transform: \"none\",\n },\n },\n zoom: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n ...translate3d(0, 0, 0),\n ...scale(1),\n },\n },\n slide: {\n from: {\n visibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {\n visibility: \"visible\",\n ...translate3d(0, 0, 0),\n },\n },\n flip: {\n from: {\n backfaceVisibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {},\n },\n} satisfies Record<string, AnimationPreset>;\n\n/** 動畫定義 */\nconst definitions = {\n fade: {\n preset: presets.fade,\n vars: {\n from: {},\n to: {},\n },\n },\n fadeUp: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, DISTANCE, 0),\n to: {},\n },\n },\n fadeDown: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, -DISTANCE, 0),\n to: {},\n },\n },\n fadeLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeUpRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeUpLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeDownRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n fadeDownLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n flipUp: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipDown: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipLeft: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n flipRight: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n slideUp: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"100%\", 0),\n to: {},\n },\n },\n slideDown: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"-100%\", 0),\n to: {},\n },\n },\n slideLeft: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"100%\", 0, 0),\n to: {},\n },\n },\n slideRight: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"-100%\", 0, 0),\n to: {},\n },\n },\n zoomIn: { preset: presets.zoom, vars: { from: scale(0.6), to: {} } },\n zoomInUp: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInDown: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, -DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInLeft: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInRight: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(-DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomOut: { preset: presets.zoom, vars: { from: scale(1.2), to: {} } },\n zoomOutUp: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutDown: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, -DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutLeft: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutRight: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(-DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n} satisfies Record<string, AnimationDefinitions>;\n\nexport default definitions;\n","import parseAttributes from \"./utils/parseAttributes\";\nimport animations, { type CreateAnimationFunction } from \"./animations\";\n\nimport type { Animation, AnimationOptions } from \"@/types\";\n\nconst ANIMATION_REGISTRY: Record<Animation, CreateAnimationFunction> = {\n fade: animations.fade,\n \"fade-up\": animations.fadeUp,\n \"fade-down\": animations.fadeDown,\n \"fade-left\": animations.fadeLeft,\n \"fade-right\": animations.fadeRight,\n \"fade-up-right\": animations.fadeUpRight,\n \"fade-up-left\": animations.fadeUpLeft,\n \"fade-down-right\": animations.fadeDownRight,\n \"fade-down-left\": animations.fadeDownLeft,\n \"flip-up\": animations.flipUp,\n \"flip-down\": animations.flipDown,\n \"flip-left\": animations.flipLeft,\n \"flip-right\": animations.flipRight,\n \"slide-up\": animations.slideUp,\n \"slide-down\": animations.slideDown,\n \"slide-left\": animations.slideLeft,\n \"slide-right\": animations.slideRight,\n \"zoom-in\": animations.zoomIn,\n \"zoom-in-up\": animations.zoomInUp,\n \"zoom-in-down\": animations.zoomInDown,\n \"zoom-in-left\": animations.zoomInLeft,\n \"zoom-in-right\": animations.zoomInRight,\n \"zoom-out\": animations.zoomOut,\n \"zoom-out-up\": animations.zoomOutUp,\n \"zoom-out-down\": animations.zoomOutDown,\n \"zoom-out-left\": animations.zoomOutLeft,\n \"zoom-out-right\": animations.zoomOutRight,\n};\n\n/** 建立動畫元素 */\nexport default function createAnimation<E extends HTMLElement>(\n element: E,\n options?: Partial<AnimationOptions>,\n) {\n const animate = element.getAttribute(\"data-aos\") as Animation | null;\n if (!animate) return;\n\n const handleAnimation = ANIMATION_REGISTRY[animate];\n if (!handleAnimation) return;\n\n return handleAnimation(element, {\n ...options,\n ...parseAttributes(element),\n });\n}\n","/** 區塊元素標籤 */\nexport type BlockElementTag =\n | \"address\"\n | \"article\"\n | \"aside\"\n | \"blockquote\"\n | \"canvas\"\n | \"dd\"\n | \"div\"\n | \"dl\"\n | \"dt\"\n | \"fieldset\"\n | \"figcaption\"\n | \"figure\"\n | \"footer\"\n | \"form\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"header\"\n | \"hr\"\n | \"li\"\n | \"main\"\n | \"nav\"\n | \"noscript\"\n | \"ol\"\n | \"p\"\n | \"pre\"\n | \"section\"\n | \"table\"\n | \"tfoot\"\n | \"ul\"\n | \"video\";\n\n/** 區塊元素標籤清單 */\nconst BLOCK_ELEMENT_TAGS: BlockElementTag[] = [\n \"address\",\n \"article\",\n \"aside\",\n \"blockquote\",\n \"canvas\",\n \"dd\",\n \"div\",\n \"dl\",\n \"dt\",\n \"fieldset\",\n \"figcaption\",\n \"figure\",\n \"footer\",\n \"form\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"header\",\n \"hr\",\n \"li\",\n \"main\",\n \"nav\",\n \"noscript\",\n \"ol\",\n \"p\",\n \"pre\",\n \"section\",\n \"table\",\n \"tfoot\",\n \"ul\",\n \"video\",\n];\n\n/**\n * 檢查標籤是否是區塊元素\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n * */\nexport default function isBlockElementTag(\n value: unknown,\n): value is BlockElementTag {\n return BLOCK_ELEMENT_TAGS.includes(value as BlockElementTag);\n}\n"],"mappings":"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","names":["gsap","definitions","gsap"]}
1
+ {"version":3,"sources":["../src/components/AOSProvider.tsx","../src/hooks/useAOSScope.ts","../src/animation/constants.ts","../src/animation/utils/parseAttributes.ts","../src/animation/animations.ts","../src/animation/utils/mergeOptions.ts","../src/animation/utils/createTweenVars.ts","../src/animation/definitions.ts","../src/animation/createAnimation.ts","../src/utils/isBlockElementTag.ts"],"sourcesContent":["\"use client\";\n\nimport { type ComponentPropsWithoutRef, createElement } from \"react\";\n\nimport useAOSScope, { type UseAOSScopeOptions } from \"@/hooks/useAOSScope\";\nimport isBlockElementTag, {\n type BlockElementTag,\n} from \"@/utils/isBlockElementTag\";\n\ntype AOSProviderProps<T extends BlockElementTag> = {\n /**\n * 要渲染的 HTML 元素標籤。\n *\n * 如果未提供或非區塊元素,預設會渲染 `<div>`。\n *\n * @default \"div\"\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n */\n component?: T;\n /**\n * 讓子元素繼承的預設動畫參數\n *\n * > 注意:預設選項只作用於後續生成的動畫,這是刻意設計的行為。\n */\n options?: UseAOSScopeOptions;\n} & ComponentPropsWithoutRef<T>;\n\n/**\n * 為子元素提供自動 AOS 動畫能力。\n *\n * 所有帶有 `data-aos` 屬性的子元素都會自動生成動畫。\n */\nexport default function AOSProvider<T extends BlockElementTag = \"div\">({\n component,\n options,\n children,\n ...props\n}: AOSProviderProps<T>) {\n const { containerRef } = useAOSScope(options);\n\n return createElement(\n isBlockElementTag(component) ? component : \"div\",\n { ...props, ref: containerRef },\n children,\n );\n}\n","import { useLayoutEffect, useRef } from \"react\";\nimport { useGSAP } from \"@gsap/react\";\nimport gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\nimport createAnimation from \"@/animation/createAnimation\";\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ngsap.registerPlugin(useGSAP, ScrollTrigger);\n\nexport type UseAOSScopeOptions = Partial<AnimationOptions>;\n\n/** AOS 屬性 */\nconst AOS_ATTRIBUTE_KEYS: (AOSAttributeKey | \"data-aos\")[] = [\n \"data-aos\",\n \"data-aos-offset\",\n \"data-aos-delay\",\n \"data-aos-duration\",\n \"data-aos-easing\",\n \"data-aos-mirror\",\n \"data-aos-once\",\n \"data-aos-anchor-placement\",\n \"data-aos-markers\",\n];\n/** AOS 屬性名稱 */\nconst AOS_QUALIFIED_NAME = \"data-aos\";\n/** AOS 選擇器 */\nconst AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;\n\n/**\n * 綁定 AOS 動畫範圍\n * \n * @example\n * ```tsx\n \"use client\";\n\n import {useAOSScope} from '@/aos';\n \n export default function Demo() {\n const {containerRef} = useAOSScope<HTMLDivElement>()\n return (\n <div ref={containerRef} className=\"overflow-hidden\">\n <div data-aos-container>\n <div data-aos=\"fade-up\">Hello AOS</div>\n </div>\n </div>\n )\n }\n * ```\n */\nexport default function useAOSScope<E extends HTMLElement = HTMLElement>(\n /** 預設動畫選項 */\n options?: UseAOSScopeOptions,\n) {\n const containerRef = useRef<E | null>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n /** 記錄每個元素對應的動畫實例 */\n const elementAnimationsRef = useRef<WeakMap<HTMLElement, gsap.core.Tween>>(\n new WeakMap(),\n );\n const currentOptionsRef = useRef(options);\n const rafIdRef = useRef<number>(0);\n const shouldRefreshRef = useRef(false);\n\n // 下次新增動畫才會套用覆蓋預設值\n useLayoutEffect(() => {\n currentOptionsRef.current = options;\n }, [options]);\n\n useGSAP(\n (_, contextSafe) => {\n if (!containerRef.current || !contextSafe) return;\n\n /** 新增動畫 */\n const addAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n if (elementAnimations.has(element)) return;\n\n const newAnimation = contextSafe(createAnimation)(\n element,\n currentOptionsRef.current,\n );\n if (!newAnimation) return;\n\n elementAnimations.set(element, newAnimation);\n };\n\n /** 移除動畫 */\n const removeAnimation = (element: HTMLElement) => {\n const elementAnimations = elementAnimationsRef.current;\n\n const animation = elementAnimations.get(element);\n if (!animation) return;\n\n animation.revert();\n elementAnimations.delete(element);\n };\n\n /** 更新動畫 */\n const updateAnimation = (element: HTMLElement) => {\n removeAnimation(element);\n addAnimation(element);\n };\n\n /** 監聽元素變化 */\n const handleMutation: MutationCallback = (mutations) => {\n const removedElements = new Set<HTMLElement>();\n const addedElements = new Set<HTMLElement>();\n const updatedElements = new Set<HTMLElement>();\n\n for (const mutation of mutations) {\n const { type, target, addedNodes, removedNodes } = mutation;\n\n if (type === \"attributes\" && target instanceof HTMLElement) {\n // 沒有指定 'data-aos' 就不處理相關邏輯\n if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;\n updatedElements.add(target);\n } else if (type === \"childList\") {\n collectElements(addedNodes, addedElements);\n collectElements(removedNodes, removedElements);\n }\n }\n\n // 移除 => 新增 => 更新\n for (const element of removedElements) removeAnimation(element);\n for (const element of addedElements) addAnimation(element);\n for (const element of updatedElements) updateAnimation(element);\n\n if (addedElements.size > 0 || removedElements.size > 0) {\n shouldRefreshRef.current = true;\n }\n };\n\n /**\n * ScrollTrigger 刷新\n *\n * > `ScrollTrigger.refresh()` 會導致無限觸發滾動事件、攔截 `window.scroll`\n *\n * > MutationObserver 變化後才會重新開啟避免無限刷新\n * */\n const updateScrollTrigger = () => {\n if (!shouldRefreshRef.current || rafIdRef.current) return;\n\n rafIdRef.current = requestAnimationFrame(() => {\n ScrollTrigger.refresh();\n shouldRefreshRef.current = false;\n rafIdRef.current = 0;\n });\n };\n\n // 初始化\n for (const element of gsap.utils.toArray<HTMLElement>(\n AOS_SELECTORS,\n containerRef.current,\n )) {\n addAnimation(element);\n }\n\n window.addEventListener(\"scroll\", updateScrollTrigger, { passive: true });\n observerRef.current = new MutationObserver(handleMutation);\n observerRef.current.observe(containerRef.current, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: AOS_ATTRIBUTE_KEYS,\n });\n\n return () => {\n window.removeEventListener(\"scroll\", updateScrollTrigger);\n\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n };\n },\n { scope: containerRef, dependencies: [] },\n );\n\n return { containerRef };\n}\n\n/** 搜尋 [data-aos] 變動元素 */\nfunction collectElements(nodes: NodeList, result: Set<HTMLElement>) {\n for (const node of nodes) {\n if (!(node instanceof HTMLElement)) continue;\n\n if (node.hasAttribute(AOS_QUALIFIED_NAME)) {\n result.add(node);\n }\n\n for (const element of node.querySelectorAll<HTMLElement>(AOS_SELECTORS)) {\n result.add(element);\n }\n }\n}\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n markers: false,\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"../constants\";\n\nimport type { AnimationOptions, AOSAttributeKey } from \"@/types\";\n\n/** AOS 屬性對應 */\nconst AOS_ATTRIBUTE_MAP = {\n \"data-aos-offset\": \"offset\",\n \"data-aos-delay\": \"delay\",\n \"data-aos-duration\": \"duration\",\n \"data-aos-easing\": \"easing\",\n \"data-aos-mirror\": \"mirror\",\n \"data-aos-once\": \"once\",\n \"data-aos-anchor-placement\": \"anchorPlacement\",\n \"data-aos-markers\": \"markers\",\n} satisfies Record<AOSAttributeKey, keyof AnimationOptions>;\n\n/** 解析動畫屬性 */\nexport default function parseAttributes<E extends Element>(element: E) {\n const options = {} as Partial<AnimationOptions>;\n\n for (const key of Object.keys(AOS_ATTRIBUTE_MAP)) {\n const value = element.getAttribute(key);\n\n if (value) {\n const prop = AOS_ATTRIBUTE_MAP[key as AOSAttributeKey];\n\n switch (prop) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n const numberValue = parseNumber(value);\n if (Number.isInteger(numberValue)) {\n options[prop] = numberValue;\n }\n break;\n case \"once\":\n case \"mirror\":\n case \"markers\":\n const booleanValue = parseBoolean(value);\n if (typeof booleanValue === \"boolean\") {\n options[prop] = booleanValue;\n }\n break;\n case \"easing\":\n const easing = parseEnum(easings, value);\n if (easing) {\n options[prop] = easing;\n }\n break;\n case \"anchorPlacement\":\n const anchorPlacement = parseEnum(anchorPlacements, value);\n if (anchorPlacement) {\n options[prop] = anchorPlacement;\n }\n break;\n }\n }\n }\n\n return options;\n}\n\nfunction parseEnum<T extends string>(\n list: readonly T[],\n value: string,\n): T | undefined {\n return list.includes(value as T) ? (value as T) : undefined;\n}\n\nfunction parseBoolean(value: string) {\n switch (value) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return undefined;\n }\n}\n\nfunction parseNumber(value: string) {\n const num = Number(value);\n return Number.isInteger(num) ? num : undefined;\n}\n","import gsap from \"gsap\";\n\nimport mergeOptions from \"./utils/mergeOptions\";\nimport definitions, {\n AnimationDefinitions,\n AnimationPreset,\n} from \"./definitions\";\n\nimport type { AnchorPlacement, AnimationOptions } from \"@/types\";\n\nexport type CreateAnimationFunction = (\n element: HTMLElement,\n options?: Partial<AnimationOptions>,\n) => gsap.core.Tween;\n\n/** 解析 ScrollTrigger 的 `start` */\nfunction resolveScrollTriggerStart(\n anchorPlacement: AnchorPlacement,\n offset: number,\n): string {\n const [v1, v2] = anchorPlacement.split(\"-\");\n const anchor = `${v1} ${v2}`;\n\n if (offset === 0 || !Number.isFinite(offset)) return anchor;\n\n const fix = `${offset > 0 ? \"-\" : \"+\"}=${Math.abs(offset)}`;\n return `${anchor}${fix}`;\n}\n\n/** 解析 ScrollTrigger 的 `toggleActions` */\nfunction resolveToggleActions(once?: boolean, mirror?: boolean): string {\n if (once) return \"play none none none\";\n if (mirror) return \"play reverse play reverse\";\n return \"play none none reverse\";\n}\n\n/** 毫秒單位 */\nconst UNIT_MS = 1000;\n\n/** 建立 ScrollTrigger 動畫 */\nfunction createScrollTriggerTween(\n element: HTMLElement,\n preset: AnimationPreset,\n vars: AnimationPreset,\n options?: Partial<AnimationOptions>,\n) {\n const { from, to } = vars;\n const { parentElement } = element;\n const {\n offset,\n delay,\n duration,\n easing,\n once,\n mirror,\n anchorPlacement,\n markers,\n } = mergeOptions(options);\n\n return gsap.fromTo(\n element,\n {\n ...preset.from,\n ...from,\n },\n {\n ...preset.to,\n ...to,\n ease: easing,\n duration: duration / UNIT_MS,\n delay: delay / UNIT_MS,\n overwrite: \"auto\",\n scrollTrigger: {\n markers,\n invalidateOnRefresh: true,\n // 優先使用上一層被標記的動畫容器\n trigger: parentElement?.hasAttribute(\"data-aos-container\")\n ? parentElement\n : element,\n toggleActions: resolveToggleActions(once, mirror),\n start: resolveScrollTriggerStart(anchorPlacement, offset),\n },\n },\n );\n}\n\n/** 建立動畫物件組 */\nfunction createAnimationMap<T extends Record<string, AnimationDefinitions>>(\n definitions: T,\n): { [K in keyof T]: CreateAnimationFunction } {\n const result = {} as Record<keyof T, CreateAnimationFunction>;\n const keys = Object.keys(definitions) as Array<keyof T>;\n\n for (const key of keys) {\n const { preset, vars } = definitions[key];\n\n result[key] = (element, options) =>\n createScrollTriggerTween(element, preset, vars, options);\n }\n\n return result;\n}\n\nconst animations = createAnimationMap(definitions);\n\nexport default animations;\n","import { anchorPlacements, DEFAULT_OPTIONS, easings } from \"../constants\";\n\nimport type { AnimationOptions } from \"@/types\";\n\n/** 跟預設值合併動畫選項 */\nexport default function mergeOptions(\n ...array: (Partial<AnimationOptions> | undefined | null)[]\n): AnimationOptions {\n const result = { ...DEFAULT_OPTIONS };\n\n for (const options of array) {\n if (!options) continue;\n\n for (const key of Object.keys(options) as (keyof AnimationOptions)[]) {\n const value = options[key];\n\n switch (key) {\n case \"offset\":\n case \"delay\":\n case \"duration\":\n if (typeof value === \"number\" && Number.isInteger(value)) {\n result[key] = value;\n }\n break;\n case \"once\":\n case \"mirror\":\n case \"markers\":\n if (typeof value === \"boolean\") {\n result[key] = value;\n }\n break;\n case \"easing\":\n if (verifyEnum(easings, value)) {\n result[key] = value;\n }\n break;\n case \"anchorPlacement\":\n if (verifyEnum(anchorPlacements, value)) {\n result[key] = value;\n }\n break;\n default:\n break;\n }\n }\n }\n\n return result;\n}\n\nfunction verifyEnum<T>(list: readonly T[], value: unknown): value is T {\n return list.includes(value as T);\n}\n","export function translate3d(x: number | string, y: number | string, z: number) {\n return { x, y, z } satisfies gsap.TweenVars;\n}\n\nexport function rotateY(y: number | string) {\n return { rotateY: y } satisfies gsap.TweenVars;\n}\n\nexport function rotateX(x: number | string) {\n return { rotateX: x } satisfies gsap.TweenVars;\n}\n\nexport function scale(x: number, y?: number) {\n return typeof y === \"number\"\n ? ({\n scaleX: x,\n scaleY: y,\n } satisfies gsap.TweenVars)\n : ({\n scale: x,\n } satisfies gsap.TweenVars);\n}\n\n/** @see https://gsap.com/docs/v3/GSAP/CorePlugins/CSS/#3d-transforms */\nexport function perspective(value: number) {\n return {\n transformPerspective: value,\n } satisfies gsap.TweenVars;\n}\n","import {\n perspective,\n rotateX,\n rotateY,\n scale,\n translate3d,\n} from \"./utils/createTweenVars\";\n\n/** 動畫配置 */\nexport interface AnimationPreset {\n /** 動畫起點 */\n from: gsap.TweenVars;\n /** 動畫終點 */\n to: gsap.TweenVars;\n}\n\n/** 動畫定義 */\nexport interface AnimationDefinitions {\n /** 預設配置 */\n preset: AnimationPreset;\n /** 自訂配置 */\n vars: AnimationPreset;\n}\n\n/** 距離 `px` */\nexport const DISTANCE = 100;\n\n/** 動畫預設配置 */\nconst presets = {\n fade: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n transform: \"none\",\n },\n },\n zoom: {\n from: {\n opacity: 0,\n transitionProperty: \"opacity, transform\",\n },\n to: {\n opacity: 1,\n ...translate3d(0, 0, 0),\n ...scale(1),\n },\n },\n slide: {\n from: {\n visibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {\n visibility: \"visible\",\n ...translate3d(0, 0, 0),\n },\n },\n flip: {\n from: {\n backfaceVisibility: \"hidden\",\n transitionProperty: \"transform\",\n },\n to: {},\n },\n} satisfies Record<string, AnimationPreset>;\n\n/** 動畫定義 */\nconst definitions = {\n fade: {\n preset: presets.fade,\n vars: {\n from: {},\n to: {},\n },\n },\n fadeUp: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, DISTANCE, 0),\n to: {},\n },\n },\n fadeDown: {\n preset: presets.fade,\n vars: {\n from: translate3d(0, -DISTANCE, 0),\n to: {},\n },\n },\n fadeLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, 0, 0),\n to: {},\n },\n },\n fadeUpRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeUpLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, DISTANCE, 0),\n to: {},\n },\n },\n fadeDownRight: {\n preset: presets.fade,\n vars: {\n from: translate3d(-DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n fadeDownLeft: {\n preset: presets.fade,\n vars: {\n from: translate3d(DISTANCE, -DISTANCE, 0),\n to: {},\n },\n },\n flipUp: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipDown: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateX(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateX(0) },\n },\n },\n flipLeft: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"-100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n flipRight: {\n preset: presets.flip,\n vars: {\n from: {\n ...perspective(2500),\n ...rotateY(\"100deg\"),\n },\n to: { ...perspective(2500), ...rotateY(0) },\n },\n },\n slideUp: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"100%\", 0),\n to: {},\n },\n },\n slideDown: {\n preset: presets.slide,\n vars: {\n from: translate3d(0, \"-100%\", 0),\n to: {},\n },\n },\n slideLeft: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"100%\", 0, 0),\n to: {},\n },\n },\n slideRight: {\n preset: presets.slide,\n vars: {\n from: translate3d(\"-100%\", 0, 0),\n to: {},\n },\n },\n zoomIn: { preset: presets.zoom, vars: { from: scale(0.6), to: {} } },\n zoomInUp: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInDown: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(0, -DISTANCE, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInLeft: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomInRight: {\n preset: presets.zoom,\n vars: {\n from: { ...translate3d(-DISTANCE, 0, 0), ...scale(0.6) },\n to: {},\n },\n },\n zoomOut: { preset: presets.zoom, vars: { from: scale(1.2), to: {} } },\n zoomOutUp: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutDown: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(0, -DISTANCE, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutLeft: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n zoomOutRight: {\n preset: presets.zoom,\n vars: {\n from: {\n ...translate3d(-DISTANCE, 0, 0),\n ...scale(1.2),\n },\n to: {},\n },\n },\n} satisfies Record<string, AnimationDefinitions>;\n\nexport default definitions;\n","import parseAttributes from \"./utils/parseAttributes\";\nimport animations, { type CreateAnimationFunction } from \"./animations\";\n\nimport type { Animation, AnimationOptions } from \"@/types\";\n\nconst ANIMATION_REGISTRY: Record<Animation, CreateAnimationFunction> = {\n fade: animations.fade,\n \"fade-up\": animations.fadeUp,\n \"fade-down\": animations.fadeDown,\n \"fade-left\": animations.fadeLeft,\n \"fade-right\": animations.fadeRight,\n \"fade-up-right\": animations.fadeUpRight,\n \"fade-up-left\": animations.fadeUpLeft,\n \"fade-down-right\": animations.fadeDownRight,\n \"fade-down-left\": animations.fadeDownLeft,\n \"flip-up\": animations.flipUp,\n \"flip-down\": animations.flipDown,\n \"flip-left\": animations.flipLeft,\n \"flip-right\": animations.flipRight,\n \"slide-up\": animations.slideUp,\n \"slide-down\": animations.slideDown,\n \"slide-left\": animations.slideLeft,\n \"slide-right\": animations.slideRight,\n \"zoom-in\": animations.zoomIn,\n \"zoom-in-up\": animations.zoomInUp,\n \"zoom-in-down\": animations.zoomInDown,\n \"zoom-in-left\": animations.zoomInLeft,\n \"zoom-in-right\": animations.zoomInRight,\n \"zoom-out\": animations.zoomOut,\n \"zoom-out-up\": animations.zoomOutUp,\n \"zoom-out-down\": animations.zoomOutDown,\n \"zoom-out-left\": animations.zoomOutLeft,\n \"zoom-out-right\": animations.zoomOutRight,\n};\n\n/** 建立動畫元素 */\nexport default function createAnimation<E extends HTMLElement>(\n element: E,\n options?: Partial<AnimationOptions>,\n) {\n const animate = element.getAttribute(\"data-aos\") as Animation | null;\n if (!animate) return;\n\n const handleAnimation = ANIMATION_REGISTRY[animate];\n if (!handleAnimation) return;\n\n return handleAnimation(element, {\n ...options,\n ...parseAttributes(element),\n });\n}\n","/** 區塊元素標籤 */\nexport type BlockElementTag =\n | \"address\"\n | \"article\"\n | \"aside\"\n | \"blockquote\"\n | \"canvas\"\n | \"dd\"\n | \"div\"\n | \"dl\"\n | \"dt\"\n | \"fieldset\"\n | \"figcaption\"\n | \"figure\"\n | \"footer\"\n | \"form\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"header\"\n | \"hr\"\n | \"li\"\n | \"main\"\n | \"nav\"\n | \"noscript\"\n | \"ol\"\n | \"p\"\n | \"pre\"\n | \"section\"\n | \"table\"\n | \"tfoot\"\n | \"ul\"\n | \"video\";\n\n/** 區塊元素標籤清單 */\nconst BLOCK_ELEMENT_TAGS: BlockElementTag[] = [\n \"address\",\n \"article\",\n \"aside\",\n \"blockquote\",\n \"canvas\",\n \"dd\",\n \"div\",\n \"dl\",\n \"dt\",\n \"fieldset\",\n \"figcaption\",\n \"figure\",\n \"footer\",\n \"form\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"header\",\n \"hr\",\n \"li\",\n \"main\",\n \"nav\",\n \"noscript\",\n \"ol\",\n \"p\",\n \"pre\",\n \"section\",\n \"table\",\n \"tfoot\",\n \"ul\",\n \"video\",\n];\n\n/**\n * 檢查標籤是否是區塊元素\n *\n * @see https://www.w3schools.com/html/html_blocks.asp\n * */\nexport default function isBlockElementTag(\n value: unknown,\n): value is BlockElementTag {\n return BLOCK_ELEMENT_TAGS.includes(value as BlockElementTag);\n}\n"],"mappings":"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","names":["gsap","definitions","gsap"]}
@@ -1,4 +1,4 @@
1
- import { c as AnchorPlacement, E as Easing, a as Animation } from './types-D2cyob0n.mjs';
1
+ import { c as AnchorPlacement, E as Easing, a as Animation } from './types-CQ3qrMsE.mjs';
2
2
 
3
3
  /** 動畫曲線 */
4
4
  declare const easings: Easing[];
@@ -1,4 +1,4 @@
1
- import { c as AnchorPlacement, E as Easing, a as Animation } from './types-D2cyob0n.js';
1
+ import { c as AnchorPlacement, E as Easing, a as Animation } from './types-CQ3qrMsE.js';
2
2
 
3
3
  /** 動畫曲線 */
4
4
  declare const easings: Easing[];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/animation/constants.ts"],"sourcesContent":["import type { Animation } from \"./types\";\n\nexport { anchorPlacements, easings } from \"./animation/constants\";\n\n/** 動畫種類 */\nexport const animations: Animation[] = [\n \"fade\",\n \"fade-up\",\n \"fade-down\",\n \"fade-left\",\n \"fade-right\",\n \"fade-up-right\",\n \"fade-up-left\",\n \"fade-down-right\",\n \"fade-down-left\",\n \"flip-up\",\n \"flip-down\",\n \"flip-left\",\n \"flip-right\",\n \"slide-up\",\n \"slide-down\",\n \"slide-left\",\n \"slide-right\",\n \"zoom-in\",\n \"zoom-in-up\",\n \"zoom-in-down\",\n \"zoom-in-left\",\n \"zoom-in-right\",\n \"zoom-out\",\n \"zoom-out-up\",\n \"zoom-out-down\",\n \"zoom-out-left\",\n \"zoom-out-right\",\n];\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACcO,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ADhEO,IAAM,aAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/animation/constants.ts"],"sourcesContent":["import type { Animation } from \"./types\";\n\nexport { anchorPlacements, easings } from \"./animation/constants\";\n\n/** 動畫種類 */\nexport const animations: Animation[] = [\n \"fade\",\n \"fade-up\",\n \"fade-down\",\n \"fade-left\",\n \"fade-right\",\n \"fade-up-right\",\n \"fade-up-left\",\n \"fade-down-right\",\n \"fade-down-left\",\n \"flip-up\",\n \"flip-down\",\n \"flip-left\",\n \"flip-right\",\n \"slide-up\",\n \"slide-down\",\n \"slide-left\",\n \"slide-right\",\n \"zoom-in\",\n \"zoom-in-up\",\n \"zoom-in-down\",\n \"zoom-in-left\",\n \"zoom-in-right\",\n \"zoom-out\",\n \"zoom-out-up\",\n \"zoom-out-down\",\n \"zoom-out-left\",\n \"zoom-out-right\",\n];\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n markers: false,\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACeO,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ADjEO,IAAM,aAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/animation/constants.ts","../src/constants.ts"],"sourcesContent":["import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import type { Animation } from \"./types\";\n\nexport { anchorPlacements, easings } from \"./animation/constants\";\n\n/** 動畫種類 */\nexport const animations: Animation[] = [\n \"fade\",\n \"fade-up\",\n \"fade-down\",\n \"fade-left\",\n \"fade-right\",\n \"fade-up-right\",\n \"fade-up-left\",\n \"fade-down-right\",\n \"fade-down-left\",\n \"flip-up\",\n \"flip-down\",\n \"flip-left\",\n \"flip-right\",\n \"slide-up\",\n \"slide-down\",\n \"slide-left\",\n \"slide-right\",\n \"zoom-in\",\n \"zoom-in-up\",\n \"zoom-in-down\",\n \"zoom-in-left\",\n \"zoom-in-right\",\n \"zoom-out\",\n \"zoom-out-up\",\n \"zoom-out-down\",\n \"zoom-out-left\",\n \"zoom-out-right\",\n];\n"],"mappings":";AAcO,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AChEO,IAAM,aAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/animation/constants.ts","../src/constants.ts"],"sourcesContent":["import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n markers: false,\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import type { Animation } from \"./types\";\n\nexport { anchorPlacements, easings } from \"./animation/constants\";\n\n/** 動畫種類 */\nexport const animations: Animation[] = [\n \"fade\",\n \"fade-up\",\n \"fade-down\",\n \"fade-left\",\n \"fade-right\",\n \"fade-up-right\",\n \"fade-up-left\",\n \"fade-down-right\",\n \"fade-down-left\",\n \"flip-up\",\n \"flip-down\",\n \"flip-left\",\n \"flip-right\",\n \"slide-up\",\n \"slide-down\",\n \"slide-left\",\n \"slide-right\",\n \"zoom-in\",\n \"zoom-in-up\",\n \"zoom-in-down\",\n \"zoom-in-left\",\n \"zoom-in-right\",\n \"zoom-out\",\n \"zoom-out-up\",\n \"zoom-out-down\",\n \"zoom-out-left\",\n \"zoom-out-right\",\n];\n"],"mappings":";AAeO,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACjEO,IAAM,aAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,14 +1,8 @@
1
- import { A as AnimationOptions, a as Animation, b as AOSAttributeKey } from './types-D2cyob0n.mjs';
2
- export { c as AnchorPlacement, E as Easing, F as FadeAnimation, d as FlipAnimation, S as SlideAnimation, Z as ZoomAnimation } from './types-D2cyob0n.mjs';
1
+ import { A as AnimationOptions, a as Animation, b as AOSAttributeKey } from './types-CQ3qrMsE.mjs';
2
+ export { c as AnchorPlacement, E as Easing, F as FadeAnimation, d as FlipAnimation, S as SlideAnimation, Z as ZoomAnimation } from './types-CQ3qrMsE.mjs';
3
3
 
4
- /**
5
- * 刷新 AOS 動畫位置
6
- *
7
- * > 目前只是封裝了 ScrollTrigger.refresh(),未添加額外邏輯。
8
- *
9
- * > 封裝此函式是為了未來可以在刷新時加入自定義處理。
10
- */
11
- declare const refreshAOS: typeof globalThis.ScrollTrigger.refresh;
4
+ /** 原始 ScrollTrigger.refresh */
5
+ declare function refreshScrollTrigger(safe?: boolean | undefined): void;
12
6
 
13
7
  interface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {
14
8
  "data-aos": Animation;
@@ -19,4 +13,4 @@ interface AOSAttributeOptions extends Partial<AnimationOptions> {
19
13
  /** 將 options 轉成可直接使用的 AOS data attributes */
20
14
  declare function toAOSProps(options?: AOSAttributeOptions): Partial<AOSDataAttributes>;
21
15
 
22
- export { Animation, AnimationOptions, refreshAOS, toAOSProps };
16
+ export { Animation, AnimationOptions, refreshScrollTrigger, toAOSProps };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,8 @@
1
- import { A as AnimationOptions, a as Animation, b as AOSAttributeKey } from './types-D2cyob0n.js';
2
- export { c as AnchorPlacement, E as Easing, F as FadeAnimation, d as FlipAnimation, S as SlideAnimation, Z as ZoomAnimation } from './types-D2cyob0n.js';
1
+ import { A as AnimationOptions, a as Animation, b as AOSAttributeKey } from './types-CQ3qrMsE.js';
2
+ export { c as AnchorPlacement, E as Easing, F as FadeAnimation, d as FlipAnimation, S as SlideAnimation, Z as ZoomAnimation } from './types-CQ3qrMsE.js';
3
3
 
4
- /**
5
- * 刷新 AOS 動畫位置
6
- *
7
- * > 目前只是封裝了 ScrollTrigger.refresh(),未添加額外邏輯。
8
- *
9
- * > 封裝此函式是為了未來可以在刷新時加入自定義處理。
10
- */
11
- declare const refreshAOS: typeof globalThis.ScrollTrigger.refresh;
4
+ /** 原始 ScrollTrigger.refresh */
5
+ declare function refreshScrollTrigger(safe?: boolean | undefined): void;
12
6
 
13
7
  interface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {
14
8
  "data-aos": Animation;
@@ -19,4 +13,4 @@ interface AOSAttributeOptions extends Partial<AnimationOptions> {
19
13
  /** 將 options 轉成可直接使用的 AOS data attributes */
20
14
  declare function toAOSProps(options?: AOSAttributeOptions): Partial<AOSDataAttributes>;
21
15
 
22
- export { Animation, AnimationOptions, refreshAOS, toAOSProps };
16
+ export { Animation, AnimationOptions, refreshScrollTrigger, toAOSProps };
package/dist/index.js CHANGED
@@ -30,17 +30,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
- refreshAOS: () => refreshAOS_default,
33
+ refreshScrollTrigger: () => refreshScrollTrigger,
34
34
  toAOSProps: () => toAOSProps
35
35
  });
36
36
  module.exports = __toCommonJS(src_exports);
37
37
 
38
- // src/utils/refreshAOS.ts
38
+ // src/utils/refreshScrollTrigger.ts
39
39
  var import_gsap = __toESM(require("gsap"));
40
40
  var import_ScrollTrigger = require("gsap/ScrollTrigger");
41
41
  import_gsap.default.registerPlugin(import_ScrollTrigger.ScrollTrigger);
42
- var refreshAOS = import_ScrollTrigger.ScrollTrigger.refresh;
43
- var refreshAOS_default = refreshAOS;
42
+ function refreshScrollTrigger(safe) {
43
+ import_ScrollTrigger.ScrollTrigger.refresh(safe);
44
+ }
44
45
 
45
46
  // src/animation/constants.ts
46
47
  var easings = [
@@ -112,7 +113,8 @@ function toAOSProps(options) {
112
113
  "data-aos-anchor-placement": validateEnumValue(
113
114
  anchorPlacements,
114
115
  options.anchorPlacement
115
- )
116
+ ),
117
+ "data-aos-markers": toBooleanAttr(options.markers)
116
118
  });
117
119
  }
118
120
  function omitNil(obj) {
@@ -138,7 +140,7 @@ function validateEnumValue(list, value) {
138
140
  }
139
141
  // Annotate the CommonJS export names for ESM import in node:
140
142
  0 && (module.exports = {
141
- refreshAOS,
143
+ refreshScrollTrigger,
142
144
  toAOSProps
143
145
  });
144
146
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/refreshAOS.ts","../src/animation/constants.ts","../src/utils/toAOSProps.ts"],"sourcesContent":["export type {\n AnchorPlacement,\n Animation,\n AnimationOptions,\n Easing,\n FadeAnimation,\n FlipAnimation,\n SlideAnimation,\n ZoomAnimation,\n} from \"./types\";\nexport { default as refreshAOS } from \"./utils/refreshAOS\";\nexport { default as toAOSProps } from \"./utils/toAOSProps\";\n","import gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\ngsap.registerPlugin(ScrollTrigger);\n\n/**\n * 刷新 AOS 動畫位置\n *\n * > 目前只是封裝了 ScrollTrigger.refresh(),未添加額外邏輯。\n *\n * > 封裝此函式是為了未來可以在刷新時加入自定義處理。\n */\nconst refreshAOS = ScrollTrigger.refresh;\n\nexport default refreshAOS;\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"@/constants\";\nimport type { Animation, AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ninterface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {\n \"data-aos\": Animation;\n}\n\nexport interface AOSAttributeOptions extends Partial<AnimationOptions> {\n animation: Animation;\n}\n\n/** 將 options 轉成可直接使用的 AOS data attributes */\nexport default function toAOSProps(\n options?: AOSAttributeOptions,\n): Partial<AOSDataAttributes> {\n if (!options) return {};\n\n return omitNil({\n \"data-aos\": options.animation,\n \"data-aos-offset\": toNumberAttr(options.offset),\n \"data-aos-delay\": toNumberAttr(options.delay),\n \"data-aos-duration\": toNumberAttr(options.duration),\n \"data-aos-easing\": validateEnumValue(easings, options.easing),\n \"data-aos-mirror\": toBooleanAttr(options.mirror),\n \"data-aos-once\": toBooleanAttr(options.once),\n \"data-aos-anchor-placement\": validateEnumValue(\n anchorPlacements,\n options.anchorPlacement,\n ),\n } satisfies AOSDataAttributes);\n}\n\nfunction omitNil<T extends object>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n\n const keys = Object.keys(obj) as Array<keyof T>;\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (value != null) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction toBooleanAttr(value?: boolean) {\n return typeof value === \"boolean\" ? String(value) : undefined;\n}\n\nfunction toNumberAttr(value?: number) {\n return Number.isInteger(value) ? String(value) : undefined;\n}\n\nfunction validateEnumValue<T>(list: readonly T[], value: T) {\n return list.includes(value) ? value : undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAiB;AACjB,2BAA8B;AAE9B,YAAAA,QAAK,eAAe,kCAAa;AASjC,IAAM,aAAa,mCAAc;AAEjC,IAAO,qBAAQ;;;ACAR,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACzDe,SAAR,WACL,SAC4B;AAC5B,MAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,SAAO,QAAQ;AAAA,IACb,YAAY,QAAQ;AAAA,IACpB,mBAAmB,aAAa,QAAQ,MAAM;AAAA,IAC9C,kBAAkB,aAAa,QAAQ,KAAK;AAAA,IAC5C,qBAAqB,aAAa,QAAQ,QAAQ;AAAA,IAClD,mBAAmB,kBAAkB,SAAS,QAAQ,MAAM;AAAA,IAC5D,mBAAmB,cAAc,QAAQ,MAAM;AAAA,IAC/C,iBAAiB,cAAc,QAAQ,IAAI;AAAA,IAC3C,6BAA6B;AAAA,MAC3B;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF,CAA6B;AAC/B;AAEA,SAAS,QAA0B,KAAoB;AACrD,QAAM,SAAqB,CAAC;AAE5B,QAAM,OAAO,OAAO,KAAK,GAAG;AAE5B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,QAAQ,IAAI,GAAG;AAErB,QAAI,SAAS,MAAM;AACjB,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,OAAiB;AACtC,SAAO,OAAO,UAAU,YAAY,OAAO,KAAK,IAAI;AACtD;AAEA,SAAS,aAAa,OAAgB;AACpC,SAAO,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,IAAI;AACnD;AAEA,SAAS,kBAAqB,MAAoB,OAAU;AAC1D,SAAO,KAAK,SAAS,KAAK,IAAI,QAAQ;AACxC;","names":["gsap"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/refreshScrollTrigger.ts","../src/animation/constants.ts","../src/utils/toAOSProps.ts"],"sourcesContent":["export type {\n AnchorPlacement,\n Animation,\n AnimationOptions,\n Easing,\n FadeAnimation,\n FlipAnimation,\n SlideAnimation,\n ZoomAnimation,\n} from \"./types\";\nexport { default as refreshScrollTrigger } from \"./utils/refreshScrollTrigger\";\nexport { default as toAOSProps } from \"./utils/toAOSProps\";\n","import gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\ngsap.registerPlugin(ScrollTrigger);\n\n/** 原始 ScrollTrigger.refresh */\nexport default function refreshScrollTrigger(safe?: boolean | undefined) {\n ScrollTrigger.refresh(safe);\n}\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n markers: false,\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"@/constants\";\nimport type { Animation, AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ninterface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {\n \"data-aos\": Animation;\n}\n\nexport interface AOSAttributeOptions extends Partial<AnimationOptions> {\n animation: Animation;\n}\n\n/** 將 options 轉成可直接使用的 AOS data attributes */\nexport default function toAOSProps(\n options?: AOSAttributeOptions,\n): Partial<AOSDataAttributes> {\n if (!options) return {};\n\n return omitNil({\n \"data-aos\": options.animation,\n \"data-aos-offset\": toNumberAttr(options.offset),\n \"data-aos-delay\": toNumberAttr(options.delay),\n \"data-aos-duration\": toNumberAttr(options.duration),\n \"data-aos-easing\": validateEnumValue(easings, options.easing),\n \"data-aos-mirror\": toBooleanAttr(options.mirror),\n \"data-aos-once\": toBooleanAttr(options.once),\n \"data-aos-anchor-placement\": validateEnumValue(\n anchorPlacements,\n options.anchorPlacement,\n ),\n \"data-aos-markers\": toBooleanAttr(options.markers),\n } satisfies AOSDataAttributes);\n}\n\nfunction omitNil<T extends object>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n\n const keys = Object.keys(obj) as Array<keyof T>;\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (value != null) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction toBooleanAttr(value?: boolean) {\n return typeof value === \"boolean\" ? String(value) : undefined;\n}\n\nfunction toNumberAttr(value?: number) {\n return Number.isInteger(value) ? String(value) : undefined;\n}\n\nfunction validateEnumValue<T>(list: readonly T[], value: T) {\n return list.includes(value) ? value : undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAiB;AACjB,2BAA8B;AAE9B,YAAAA,QAAK,eAAe,kCAAa;AAGlB,SAAR,qBAAsC,MAA4B;AACvE,qCAAc,QAAQ,IAAI;AAC5B;;;ACOO,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC1De,SAAR,WACL,SAC4B;AAC5B,MAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,SAAO,QAAQ;AAAA,IACb,YAAY,QAAQ;AAAA,IACpB,mBAAmB,aAAa,QAAQ,MAAM;AAAA,IAC9C,kBAAkB,aAAa,QAAQ,KAAK;AAAA,IAC5C,qBAAqB,aAAa,QAAQ,QAAQ;AAAA,IAClD,mBAAmB,kBAAkB,SAAS,QAAQ,MAAM;AAAA,IAC5D,mBAAmB,cAAc,QAAQ,MAAM;AAAA,IAC/C,iBAAiB,cAAc,QAAQ,IAAI;AAAA,IAC3C,6BAA6B;AAAA,MAC3B;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,IACA,oBAAoB,cAAc,QAAQ,OAAO;AAAA,EACnD,CAA6B;AAC/B;AAEA,SAAS,QAA0B,KAAoB;AACrD,QAAM,SAAqB,CAAC;AAE5B,QAAM,OAAO,OAAO,KAAK,GAAG;AAE5B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,QAAQ,IAAI,GAAG;AAErB,QAAI,SAAS,MAAM;AACjB,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,OAAiB;AACtC,SAAO,OAAO,UAAU,YAAY,OAAO,KAAK,IAAI;AACtD;AAEA,SAAS,aAAa,OAAgB;AACpC,SAAO,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,IAAI;AACnD;AAEA,SAAS,kBAAqB,MAAoB,OAAU;AAC1D,SAAO,KAAK,SAAS,KAAK,IAAI,QAAQ;AACxC;","names":["gsap"]}
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
- // src/utils/refreshAOS.ts
1
+ // src/utils/refreshScrollTrigger.ts
2
2
  import gsap from "gsap";
3
3
  import { ScrollTrigger } from "gsap/ScrollTrigger";
4
4
  gsap.registerPlugin(ScrollTrigger);
5
- var refreshAOS = ScrollTrigger.refresh;
6
- var refreshAOS_default = refreshAOS;
5
+ function refreshScrollTrigger(safe) {
6
+ ScrollTrigger.refresh(safe);
7
+ }
7
8
 
8
9
  // src/animation/constants.ts
9
10
  var easings = [
@@ -75,7 +76,8 @@ function toAOSProps(options) {
75
76
  "data-aos-anchor-placement": validateEnumValue(
76
77
  anchorPlacements,
77
78
  options.anchorPlacement
78
- )
79
+ ),
80
+ "data-aos-markers": toBooleanAttr(options.markers)
79
81
  });
80
82
  }
81
83
  function omitNil(obj) {
@@ -100,7 +102,7 @@ function validateEnumValue(list, value) {
100
102
  return list.includes(value) ? value : void 0;
101
103
  }
102
104
  export {
103
- refreshAOS_default as refreshAOS,
105
+ refreshScrollTrigger,
104
106
  toAOSProps
105
107
  };
106
108
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/refreshAOS.ts","../src/animation/constants.ts","../src/utils/toAOSProps.ts"],"sourcesContent":["import gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\ngsap.registerPlugin(ScrollTrigger);\n\n/**\n * 刷新 AOS 動畫位置\n *\n * > 目前只是封裝了 ScrollTrigger.refresh(),未添加額外邏輯。\n *\n * > 封裝此函式是為了未來可以在刷新時加入自定義處理。\n */\nconst refreshAOS = ScrollTrigger.refresh;\n\nexport default refreshAOS;\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"@/constants\";\nimport type { Animation, AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ninterface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {\n \"data-aos\": Animation;\n}\n\nexport interface AOSAttributeOptions extends Partial<AnimationOptions> {\n animation: Animation;\n}\n\n/** 將 options 轉成可直接使用的 AOS data attributes */\nexport default function toAOSProps(\n options?: AOSAttributeOptions,\n): Partial<AOSDataAttributes> {\n if (!options) return {};\n\n return omitNil({\n \"data-aos\": options.animation,\n \"data-aos-offset\": toNumberAttr(options.offset),\n \"data-aos-delay\": toNumberAttr(options.delay),\n \"data-aos-duration\": toNumberAttr(options.duration),\n \"data-aos-easing\": validateEnumValue(easings, options.easing),\n \"data-aos-mirror\": toBooleanAttr(options.mirror),\n \"data-aos-once\": toBooleanAttr(options.once),\n \"data-aos-anchor-placement\": validateEnumValue(\n anchorPlacements,\n options.anchorPlacement,\n ),\n } satisfies AOSDataAttributes);\n}\n\nfunction omitNil<T extends object>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n\n const keys = Object.keys(obj) as Array<keyof T>;\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (value != null) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction toBooleanAttr(value?: boolean) {\n return typeof value === \"boolean\" ? String(value) : undefined;\n}\n\nfunction toNumberAttr(value?: number) {\n return Number.isInteger(value) ? String(value) : undefined;\n}\n\nfunction validateEnumValue<T>(list: readonly T[], value: T) {\n return list.includes(value) ? value : undefined;\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,KAAK,eAAe,aAAa;AASjC,IAAM,aAAa,cAAc;AAEjC,IAAO,qBAAQ;;;ACAR,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACzDe,SAAR,WACL,SAC4B;AAC5B,MAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,SAAO,QAAQ;AAAA,IACb,YAAY,QAAQ;AAAA,IACpB,mBAAmB,aAAa,QAAQ,MAAM;AAAA,IAC9C,kBAAkB,aAAa,QAAQ,KAAK;AAAA,IAC5C,qBAAqB,aAAa,QAAQ,QAAQ;AAAA,IAClD,mBAAmB,kBAAkB,SAAS,QAAQ,MAAM;AAAA,IAC5D,mBAAmB,cAAc,QAAQ,MAAM;AAAA,IAC/C,iBAAiB,cAAc,QAAQ,IAAI;AAAA,IAC3C,6BAA6B;AAAA,MAC3B;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF,CAA6B;AAC/B;AAEA,SAAS,QAA0B,KAAoB;AACrD,QAAM,SAAqB,CAAC;AAE5B,QAAM,OAAO,OAAO,KAAK,GAAG;AAE5B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,QAAQ,IAAI,GAAG;AAErB,QAAI,SAAS,MAAM;AACjB,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,OAAiB;AACtC,SAAO,OAAO,UAAU,YAAY,OAAO,KAAK,IAAI;AACtD;AAEA,SAAS,aAAa,OAAgB;AACpC,SAAO,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,IAAI;AACnD;AAEA,SAAS,kBAAqB,MAAoB,OAAU;AAC1D,SAAO,KAAK,SAAS,KAAK,IAAI,QAAQ;AACxC;","names":[]}
1
+ {"version":3,"sources":["../src/utils/refreshScrollTrigger.ts","../src/animation/constants.ts","../src/utils/toAOSProps.ts"],"sourcesContent":["import gsap from \"gsap\";\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\";\n\ngsap.registerPlugin(ScrollTrigger);\n\n/** 原始 ScrollTrigger.refresh */\nexport default function refreshScrollTrigger(safe?: boolean | undefined) {\n ScrollTrigger.refresh(safe);\n}\n","import type { AnchorPlacement, AnimationOptions, Easing } from \"@/types\";\n\n/** 預設選項 */\nexport const DEFAULT_OPTIONS: AnimationOptions = {\n offset: 120,\n delay: 0,\n duration: 400,\n easing: \"none\",\n once: false,\n mirror: false,\n anchorPlacement: \"top-bottom\",\n markers: false,\n};\n\n/** 動畫曲線 */\nexport const easings: Easing[] = [\n \"none\",\n \"power1\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"bounce\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ\",\n \"circ.in\",\n \"circ.out\",\n \"circ.inOut\",\n \"elastic\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"expo\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"sine\",\n \"sine.in\",\n \"sine.out\",\n \"sine.inOut\",\n];\n\n/** 動畫錨點 */\nexport const anchorPlacements: AnchorPlacement[] = [\n \"top-bottom\",\n \"top-center\",\n \"top-top\",\n \"center-bottom\",\n \"center-center\",\n \"center-top\",\n \"bottom-bottom\",\n \"bottom-center\",\n \"bottom-top\",\n];\n","import { anchorPlacements, easings } from \"@/constants\";\nimport type { Animation, AnimationOptions, AOSAttributeKey } from \"@/types\";\n\ninterface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {\n \"data-aos\": Animation;\n}\n\nexport interface AOSAttributeOptions extends Partial<AnimationOptions> {\n animation: Animation;\n}\n\n/** 將 options 轉成可直接使用的 AOS data attributes */\nexport default function toAOSProps(\n options?: AOSAttributeOptions,\n): Partial<AOSDataAttributes> {\n if (!options) return {};\n\n return omitNil({\n \"data-aos\": options.animation,\n \"data-aos-offset\": toNumberAttr(options.offset),\n \"data-aos-delay\": toNumberAttr(options.delay),\n \"data-aos-duration\": toNumberAttr(options.duration),\n \"data-aos-easing\": validateEnumValue(easings, options.easing),\n \"data-aos-mirror\": toBooleanAttr(options.mirror),\n \"data-aos-once\": toBooleanAttr(options.once),\n \"data-aos-anchor-placement\": validateEnumValue(\n anchorPlacements,\n options.anchorPlacement,\n ),\n \"data-aos-markers\": toBooleanAttr(options.markers),\n } satisfies AOSDataAttributes);\n}\n\nfunction omitNil<T extends object>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n\n const keys = Object.keys(obj) as Array<keyof T>;\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (value != null) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction toBooleanAttr(value?: boolean) {\n return typeof value === \"boolean\" ? String(value) : undefined;\n}\n\nfunction toNumberAttr(value?: number) {\n return Number.isInteger(value) ? String(value) : undefined;\n}\n\nfunction validateEnumValue<T>(list: readonly T[], value: T) {\n return list.includes(value) ? value : undefined;\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,KAAK,eAAe,aAAa;AAGlB,SAAR,qBAAsC,MAA4B;AACvE,gBAAc,QAAQ,IAAI;AAC5B;;;ACOO,IAAM,UAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,mBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC1De,SAAR,WACL,SAC4B;AAC5B,MAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,SAAO,QAAQ;AAAA,IACb,YAAY,QAAQ;AAAA,IACpB,mBAAmB,aAAa,QAAQ,MAAM;AAAA,IAC9C,kBAAkB,aAAa,QAAQ,KAAK;AAAA,IAC5C,qBAAqB,aAAa,QAAQ,QAAQ;AAAA,IAClD,mBAAmB,kBAAkB,SAAS,QAAQ,MAAM;AAAA,IAC5D,mBAAmB,cAAc,QAAQ,MAAM;AAAA,IAC/C,iBAAiB,cAAc,QAAQ,IAAI;AAAA,IAC3C,6BAA6B;AAAA,MAC3B;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,IACA,oBAAoB,cAAc,QAAQ,OAAO;AAAA,EACnD,CAA6B;AAC/B;AAEA,SAAS,QAA0B,KAAoB;AACrD,QAAM,SAAqB,CAAC;AAE5B,QAAM,OAAO,OAAO,KAAK,GAAG;AAE5B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,QAAQ,IAAI,GAAG;AAErB,QAAI,SAAS,MAAM;AACjB,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,OAAiB;AACtC,SAAO,OAAO,UAAU,YAAY,OAAO,KAAK,IAAI;AACtD;AAEA,SAAS,aAAa,OAAgB;AACpC,SAAO,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,IAAI;AACnD;AAEA,SAAS,kBAAqB,MAAoB,OAAU;AAC1D,SAAO,KAAK,SAAS,KAAK,IAAI,QAAQ;AACxC;","names":[]}
@@ -46,6 +46,14 @@ interface AnimationOptions {
46
46
  * @see https://gsap.com/docs/v3/Plugins/ScrollTrigger/#start
47
47
  */
48
48
  anchorPlacement: AnchorPlacement;
49
+ /**
50
+ * 開啟 GSAP 標記模式
51
+ *
52
+ * > 此選項開啟會造成效能問題,僅提供開發使用
53
+ *
54
+ * @default false
55
+ * */
56
+ markers: boolean;
49
57
  }
50
58
  type FadeAnimation = "fade" | "fade-up" | "fade-down" | "fade-left" | "fade-right" | "fade-up-right" | "fade-up-left" | "fade-down-right" | "fade-down-left";
51
59
  type FlipAnimation = "flip-up" | "flip-down" | "flip-left" | "flip-right";
@@ -57,7 +65,7 @@ type Animation = FadeAnimation | FlipAnimation | SlideAnimation | ZoomAnimation;
57
65
  type AnchorPlacement = "top-bottom" | "top-center" | "top-top" | "center-bottom" | "center-center" | "center-top" | "bottom-bottom" | "bottom-center" | "bottom-top";
58
66
  /** 緩動曲線 */
59
67
  type Easing = "none" | "power1" | "power1.in" | "power1.out" | "power1.inOut" | "power2" | "power2.in" | "power2.out" | "power2.inOut" | "power3" | "power3.in" | "power3.out" | "power3.inOut" | "power4" | "power4.in" | "power4.out" | "power4.inOut" | "back" | "back.in" | "back.out" | "back.inOut" | "bounce" | "bounce.in" | "bounce.out" | "bounce.inOut" | "circ" | "circ.in" | "circ.out" | "circ.inOut" | "elastic" | "elastic.in" | "elastic.out" | "elastic.inOut" | "expo" | "expo.in" | "expo.out" | "expo.inOut" | "sine" | "sine.in" | "sine.out" | "sine.inOut";
60
- type AttributeKey = "offset" | "delay" | "duration" | "easing" | "once" | "mirror" | "anchor-placement";
68
+ type AttributeKey = "offset" | "delay" | "duration" | "easing" | "once" | "mirror" | "anchor-placement" | "markers";
61
69
  /** AOS 屬性 */
62
70
  type AOSAttributeKey = `data-aos-${AttributeKey}`;
63
71
 
@@ -46,6 +46,14 @@ interface AnimationOptions {
46
46
  * @see https://gsap.com/docs/v3/Plugins/ScrollTrigger/#start
47
47
  */
48
48
  anchorPlacement: AnchorPlacement;
49
+ /**
50
+ * 開啟 GSAP 標記模式
51
+ *
52
+ * > 此選項開啟會造成效能問題,僅提供開發使用
53
+ *
54
+ * @default false
55
+ * */
56
+ markers: boolean;
49
57
  }
50
58
  type FadeAnimation = "fade" | "fade-up" | "fade-down" | "fade-left" | "fade-right" | "fade-up-right" | "fade-up-left" | "fade-down-right" | "fade-down-left";
51
59
  type FlipAnimation = "flip-up" | "flip-down" | "flip-left" | "flip-right";
@@ -57,7 +65,7 @@ type Animation = FadeAnimation | FlipAnimation | SlideAnimation | ZoomAnimation;
57
65
  type AnchorPlacement = "top-bottom" | "top-center" | "top-top" | "center-bottom" | "center-center" | "center-top" | "bottom-bottom" | "bottom-center" | "bottom-top";
58
66
  /** 緩動曲線 */
59
67
  type Easing = "none" | "power1" | "power1.in" | "power1.out" | "power1.inOut" | "power2" | "power2.in" | "power2.out" | "power2.inOut" | "power3" | "power3.in" | "power3.out" | "power3.inOut" | "power4" | "power4.in" | "power4.out" | "power4.inOut" | "back" | "back.in" | "back.out" | "back.inOut" | "bounce" | "bounce.in" | "bounce.out" | "bounce.inOut" | "circ" | "circ.in" | "circ.out" | "circ.inOut" | "elastic" | "elastic.in" | "elastic.out" | "elastic.inOut" | "expo" | "expo.in" | "expo.out" | "expo.inOut" | "sine" | "sine.in" | "sine.out" | "sine.inOut";
60
- type AttributeKey = "offset" | "delay" | "duration" | "easing" | "once" | "mirror" | "anchor-placement";
68
+ type AttributeKey = "offset" | "delay" | "duration" | "easing" | "once" | "mirror" | "anchor-placement" | "markers";
61
69
  /** AOS 屬性 */
62
70
  type AOSAttributeKey = `data-aos-${AttributeKey}`;
63
71
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-gsap-aos",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "A lightweight GSAP + ScrollTrigger integration, similar in usage to AOS, specifically designed for React / Next.js.",
5
5
  "author": "Gaia Yang",
6
6
  "license": "MIT",
@@ -61,7 +61,7 @@
61
61
  "react-dom": ">=17"
62
62
  },
63
63
  "devDependencies": {
64
- "@types/node": "^20.19.35",
64
+ "@types/node": "^20.19.37",
65
65
  "@types/react": "^19.2.14",
66
66
  "@types/react-dom": "^19.2.3",
67
67
  "eslint": "^9.39.3",