react-gsap-aos 1.2.2 → 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,15 +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 ScrollTrigger calculations when DOM changes occur.
286
+ Manually refresh AOS animation positions, wrapper around [`ScrollTrigger.refresh`](<https://gsap.com/docs/v3/Plugins/ScrollTrigger/refresh()>).
287
287
 
288
288
  ```tsx
289
- import { refreshAOS } from "react-gsap-aos";
289
+ import { refreshScrollTrigger } from "react-gsap-aos";
290
290
 
291
291
  // Call after dynamic DOM changes
292
- refreshAOS();
292
+ refreshScrollTrigger();
293
293
  ```
294
294
 
295
295
  **Example with Dynamic Content:**
@@ -336,6 +336,7 @@ export default function DynamicList() {
336
336
  | `once` | `boolean` | `data-aos-once` | `false` | Animate only once |
337
337
  | `mirror` | `boolean` | `data-aos-mirror` | `false` | Reverse animation on scroll up |
338
338
  | `anchorPlacement` | `AnchorPlacement` | `data-aos-anchor-placement` | `"top-bottom"` | Trigger position |
339
+ | `markers` | `boolean` | `data-aos-markers` | `false` | ScrollTrigger markers |
339
340
 
340
341
  ## Available Types
341
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
 
@@ -202,7 +202,7 @@ import { toAOSProps } from "react-gsap-aos";
202
202
  </AOSProvider>
203
203
  ```
204
204
 
205
- > 注意:預設選項只作用於後續生成的動畫,這是刻意設計的行為。
205
+ > ⚠️ 注意:預設選項只作用於後續生成的動畫,這是刻意設計的行為。
206
206
 
207
207
  ### useAOSScope
208
208
 
@@ -279,15 +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
- DOM 變更時手動刷新 ScrollTrigger 計算。
284
+ 手動刷新 AOS 動畫位置,封裝自 [`ScrollTrigger.refresh`](<https://gsap.com/docs/v3/Plugins/ScrollTrigger/refresh()>)
285
285
 
286
286
  ```tsx
287
- import { refreshAOS } from "react-gsap-aos";
287
+ import { refreshScrollTrigger } from "react-gsap-aos";
288
288
 
289
289
  // 在動態 DOM 變更後呼叫
290
- refreshAOS();
290
+ refreshScrollTrigger();
291
291
  ```
292
292
 
293
293
  **動態內容範例:**
@@ -334,6 +334,7 @@ export default function DynamicList() {
334
334
  | `once` | `boolean` | `data-aos-once` | `false` | 只執行一次動畫 |
335
335
  | `mirror` | `boolean` | `data-aos-mirror` | `false` | 向上捲動時反轉動畫 |
336
336
  | `anchorPlacement` | `AnchorPlacement` | `data-aos-anchor-placement` | `"top-bottom"` | 錨點位置 |
337
+ | `markers` | `boolean` | `data-aos-markers` | `false` | ScrollTrigger 標記 |
337
338
 
338
339
  ## 可用型別
339
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
  }
@@ -510,23 +512,33 @@ function resolveToggleActions(once, mirror) {
510
512
  if (mirror) return "play reverse play reverse";
511
513
  return "play none none reverse";
512
514
  }
515
+ var UNIT_MS = 1e3;
513
516
  function createScrollTriggerTween(element, preset, vars, options) {
514
- var _a;
515
517
  const { from, to } = vars;
516
- const { offset, delay, duration, easing, once, mirror, anchorPlacement } = mergeOptions(options);
517
- const container = ((_a = element.parentElement) == null ? void 0 : _a.hasAttribute("data-aos-container")) ? element.parentElement : null;
518
+ const { parentElement } = element;
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),
521
532
  __spreadProps(__spreadValues(__spreadValues({}, preset.to), to), {
522
533
  ease: easing,
523
- duration: duration / 1e3,
524
- delay: delay / 1e3,
534
+ duration: duration / UNIT_MS,
535
+ delay: delay / UNIT_MS,
525
536
  overwrite: "auto",
526
537
  scrollTrigger: {
527
- // markers: true,
538
+ markers,
528
539
  invalidateOnRefresh: true,
529
- trigger: container || element,
540
+ // 優先使用上一層被標記的動畫容器
541
+ trigger: (parentElement == null ? void 0 : parentElement.hasAttribute("data-aos-container")) ? parentElement : element,
530
542
  toggleActions: resolveToggleActions(once, mirror),
531
543
  start: resolveScrollTriggerStart(anchorPlacement, offset)
532
544
  }
@@ -593,53 +605,56 @@ var AOS_ATTRIBUTE_KEYS = [
593
605
  "data-aos-easing",
594
606
  "data-aos-mirror",
595
607
  "data-aos-once",
596
- "data-aos-anchor-placement"
608
+ "data-aos-anchor-placement",
609
+ "data-aos-markers"
597
610
  ];
598
- var AOS_SELECTORS = "[data-aos]";
611
+ var AOS_QUALIFIED_NAME = "data-aos";
612
+ var AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;
599
613
  function useAOSScope(options) {
600
614
  const containerRef = (0, import_react.useRef)(null);
601
615
  const observerRef = (0, import_react.useRef)(null);
602
- const animationsWeakMap = (0, import_react.useRef)(
616
+ const elementAnimationsRef = (0, import_react.useRef)(
603
617
  /* @__PURE__ */ new WeakMap()
604
618
  );
605
- const optionsRef = (0, import_react.useRef)(options);
606
- const shouldRefresh = (0, import_react.useRef)(false);
619
+ const currentOptionsRef = (0, import_react.useRef)(options);
620
+ const rafIdRef = (0, import_react.useRef)(0);
621
+ const shouldRefreshRef = (0, import_react.useRef)(false);
607
622
  (0, import_react.useLayoutEffect)(() => {
608
- optionsRef.current = options;
623
+ currentOptionsRef.current = options;
609
624
  }, [options]);
610
625
  (0, import_react2.useGSAP)(
611
626
  (_, contextSafe) => {
612
627
  if (!containerRef.current || !contextSafe) return;
613
628
  const addAnimation = (element) => {
614
- if (animationsWeakMap.current.has(element)) return;
629
+ const elementAnimations = elementAnimationsRef.current;
630
+ if (elementAnimations.has(element)) return;
615
631
  const newAnimation = contextSafe(createAnimation)(
616
632
  element,
617
- optionsRef.current
633
+ currentOptionsRef.current
618
634
  );
619
635
  if (!newAnimation) return;
620
- animationsWeakMap.current.set(element, newAnimation);
636
+ elementAnimations.set(element, newAnimation);
621
637
  };
622
- function removeAnimation(element) {
623
- const animation = animationsWeakMap.current.get(element);
638
+ const removeAnimation = (element) => {
639
+ const elementAnimations = elementAnimationsRef.current;
640
+ const animation = elementAnimations.get(element);
624
641
  if (!animation) return;
625
642
  animation.revert();
626
- animationsWeakMap.current.delete(element);
627
- }
628
- function updateAnimation(element) {
643
+ elementAnimations.delete(element);
644
+ };
645
+ const updateAnimation = (element) => {
629
646
  removeAnimation(element);
630
647
  addAnimation(element);
631
- }
648
+ };
632
649
  const handleMutation = (mutations) => {
633
650
  const removedElements = /* @__PURE__ */ new Set();
634
651
  const addedElements = /* @__PURE__ */ new Set();
635
652
  const updatedElements = /* @__PURE__ */ new Set();
636
653
  for (const mutation of mutations) {
637
- const { type, target, addedNodes, removedNodes, attributeName } = mutation;
654
+ const { type, target, addedNodes, removedNodes } = mutation;
638
655
  if (type === "attributes" && target instanceof HTMLElement) {
656
+ if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;
639
657
  updatedElements.add(target);
640
- if (attributeName === "data-aos-anchor-placement" || attributeName === "data-aos-offset") {
641
- shouldRefresh.current = true;
642
- }
643
658
  } else if (type === "childList") {
644
659
  collectElements(addedNodes, addedElements);
645
660
  collectElements(removedNodes, removedElements);
@@ -649,21 +664,24 @@ function useAOSScope(options) {
649
664
  for (const element of addedElements) addAnimation(element);
650
665
  for (const element of updatedElements) updateAnimation(element);
651
666
  if (addedElements.size > 0 || removedElements.size > 0) {
652
- shouldRefresh.current = true;
667
+ shouldRefreshRef.current = true;
653
668
  }
654
669
  };
670
+ const updateScrollTrigger = () => {
671
+ if (!shouldRefreshRef.current || rafIdRef.current) return;
672
+ rafIdRef.current = requestAnimationFrame(() => {
673
+ import_ScrollTrigger.ScrollTrigger.refresh();
674
+ shouldRefreshRef.current = false;
675
+ rafIdRef.current = 0;
676
+ });
677
+ };
655
678
  for (const element of import_gsap2.default.utils.toArray(
656
679
  AOS_SELECTORS,
657
680
  containerRef.current
658
681
  )) {
659
682
  addAnimation(element);
660
683
  }
661
- function updateScrollTrigger() {
662
- if (!shouldRefresh.current) return;
663
- import_ScrollTrigger.ScrollTrigger.refresh();
664
- shouldRefresh.current = false;
665
- }
666
- window.addEventListener("scroll", updateScrollTrigger);
684
+ window.addEventListener("scroll", updateScrollTrigger, { passive: true });
667
685
  observerRef.current = new MutationObserver(handleMutation);
668
686
  observerRef.current.observe(containerRef.current, {
669
687
  childList: true,
@@ -686,7 +704,9 @@ function useAOSScope(options) {
686
704
  function collectElements(nodes, result) {
687
705
  for (const node of nodes) {
688
706
  if (!(node instanceof HTMLElement)) continue;
689
- if (node.matches(AOS_SELECTORS)) result.add(node);
707
+ if (node.hasAttribute(AOS_QUALIFIED_NAME)) {
708
+ result.add(node);
709
+ }
690
710
  for (const element of node.querySelectorAll(AOS_SELECTORS)) {
691
711
  result.add(element);
692
712
  }
@@ -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\n/** AOS 選擇器 */\nconst AOS_SELECTORS = \"[data-aos]\";\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 animationsWeakMap = useRef<WeakMap<HTMLElement, gsap.core.Tween>>(\n new WeakMap(),\n );\n const optionsRef = useRef(options);\n const shouldRefresh = useRef(false);\n\n // 使用靜態寫入,下次新增動畫才會套用覆蓋預設值\n useLayoutEffect(() => {\n optionsRef.current = options;\n }, [options]);\n\n useGSAP(\n (_, contextSafe) => {\n if (!containerRef.current || !contextSafe) return;\n\n /** 新增動畫 */\n const addAnimation = (element: HTMLElement) => {\n if (animationsWeakMap.current.has(element)) return;\n\n const newAnimation = contextSafe(createAnimation)(\n element,\n optionsRef.current,\n );\n if (!newAnimation) return;\n\n animationsWeakMap.current.set(element, newAnimation);\n };\n\n /** 移除動畫 */\n function removeAnimation(element: HTMLElement) {\n const animation = animationsWeakMap.current.get(element);\n if (!animation) return;\n\n animation.revert();\n animationsWeakMap.current.delete(element);\n }\n\n /** 更新動畫 */\n function 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 updatedElements.add(target);\n\n // 會影響觸發點的才開啟刷新\n if (\n attributeName === \"data-aos-anchor-placement\" ||\n attributeName === \"data-aos-offset\"\n ) {\n shouldRefresh.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 shouldRefresh.current = true;\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 /**\n * ScrollTrigger 刷新\n *\n * > `ScrollTrigger.refresh()` 會導致無限觸發滾動事件、攔截 `window.scroll`\n *\n * > MutationObserver 變化後才會重新開啟避免無限刷新\n * */\n function updateScrollTrigger() {\n if (!shouldRefresh.current) return;\n ScrollTrigger.refresh();\n shouldRefresh.current = false;\n }\n\n window.addEventListener(\"scroll\", updateScrollTrigger);\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 if (node.matches(AOS_SELECTORS)) result.add(node);\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/** 建立 ScrollTrigger 動畫 */\nfunction createScrollTriggerTween(\n element: HTMLElement,\n preset: AnimationPreset,\n vars: AnimationPreset,\n options?: Partial<AnimationOptions>,\n) {\n const { from, to } = vars;\n const { offset, delay, duration, easing, once, mirror, anchorPlacement } =\n mergeOptions(options);\n\n /** 上層基準容器 */\n const container = element.parentElement?.hasAttribute(\"data-aos-container\")\n ? element.parentElement\n : null;\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 / 1000,\n delay: delay / 1000,\n overwrite: \"auto\",\n scrollTrigger: {\n // markers: true,\n invalidateOnRefresh: true,\n trigger: container || 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
  }
@@ -476,23 +478,33 @@ function resolveToggleActions(once, mirror) {
476
478
  if (mirror) return "play reverse play reverse";
477
479
  return "play none none reverse";
478
480
  }
481
+ var UNIT_MS = 1e3;
479
482
  function createScrollTriggerTween(element, preset, vars, options) {
480
- var _a;
481
483
  const { from, to } = vars;
482
- const { offset, delay, duration, easing, once, mirror, anchorPlacement } = mergeOptions(options);
483
- const container = ((_a = element.parentElement) == null ? void 0 : _a.hasAttribute("data-aos-container")) ? element.parentElement : null;
484
+ const { parentElement } = element;
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),
487
498
  __spreadProps(__spreadValues(__spreadValues({}, preset.to), to), {
488
499
  ease: easing,
489
- duration: duration / 1e3,
490
- delay: delay / 1e3,
500
+ duration: duration / UNIT_MS,
501
+ delay: delay / UNIT_MS,
491
502
  overwrite: "auto",
492
503
  scrollTrigger: {
493
- // markers: true,
504
+ markers,
494
505
  invalidateOnRefresh: true,
495
- trigger: container || element,
506
+ // 優先使用上一層被標記的動畫容器
507
+ trigger: (parentElement == null ? void 0 : parentElement.hasAttribute("data-aos-container")) ? parentElement : element,
496
508
  toggleActions: resolveToggleActions(once, mirror),
497
509
  start: resolveScrollTriggerStart(anchorPlacement, offset)
498
510
  }
@@ -559,53 +571,56 @@ var AOS_ATTRIBUTE_KEYS = [
559
571
  "data-aos-easing",
560
572
  "data-aos-mirror",
561
573
  "data-aos-once",
562
- "data-aos-anchor-placement"
574
+ "data-aos-anchor-placement",
575
+ "data-aos-markers"
563
576
  ];
564
- var AOS_SELECTORS = "[data-aos]";
577
+ var AOS_QUALIFIED_NAME = "data-aos";
578
+ var AOS_SELECTORS = `[${AOS_QUALIFIED_NAME}]`;
565
579
  function useAOSScope(options) {
566
580
  const containerRef = useRef(null);
567
581
  const observerRef = useRef(null);
568
- const animationsWeakMap = useRef(
582
+ const elementAnimationsRef = useRef(
569
583
  /* @__PURE__ */ new WeakMap()
570
584
  );
571
- const optionsRef = useRef(options);
572
- const shouldRefresh = useRef(false);
585
+ const currentOptionsRef = useRef(options);
586
+ const rafIdRef = useRef(0);
587
+ const shouldRefreshRef = useRef(false);
573
588
  useLayoutEffect(() => {
574
- optionsRef.current = options;
589
+ currentOptionsRef.current = options;
575
590
  }, [options]);
576
591
  useGSAP(
577
592
  (_, contextSafe) => {
578
593
  if (!containerRef.current || !contextSafe) return;
579
594
  const addAnimation = (element) => {
580
- if (animationsWeakMap.current.has(element)) return;
595
+ const elementAnimations = elementAnimationsRef.current;
596
+ if (elementAnimations.has(element)) return;
581
597
  const newAnimation = contextSafe(createAnimation)(
582
598
  element,
583
- optionsRef.current
599
+ currentOptionsRef.current
584
600
  );
585
601
  if (!newAnimation) return;
586
- animationsWeakMap.current.set(element, newAnimation);
602
+ elementAnimations.set(element, newAnimation);
587
603
  };
588
- function removeAnimation(element) {
589
- const animation = animationsWeakMap.current.get(element);
604
+ const removeAnimation = (element) => {
605
+ const elementAnimations = elementAnimationsRef.current;
606
+ const animation = elementAnimations.get(element);
590
607
  if (!animation) return;
591
608
  animation.revert();
592
- animationsWeakMap.current.delete(element);
593
- }
594
- function updateAnimation(element) {
609
+ elementAnimations.delete(element);
610
+ };
611
+ const updateAnimation = (element) => {
595
612
  removeAnimation(element);
596
613
  addAnimation(element);
597
- }
614
+ };
598
615
  const handleMutation = (mutations) => {
599
616
  const removedElements = /* @__PURE__ */ new Set();
600
617
  const addedElements = /* @__PURE__ */ new Set();
601
618
  const updatedElements = /* @__PURE__ */ new Set();
602
619
  for (const mutation of mutations) {
603
- const { type, target, addedNodes, removedNodes, attributeName } = mutation;
620
+ const { type, target, addedNodes, removedNodes } = mutation;
604
621
  if (type === "attributes" && target instanceof HTMLElement) {
622
+ if (!target.hasAttribute(AOS_QUALIFIED_NAME)) continue;
605
623
  updatedElements.add(target);
606
- if (attributeName === "data-aos-anchor-placement" || attributeName === "data-aos-offset") {
607
- shouldRefresh.current = true;
608
- }
609
624
  } else if (type === "childList") {
610
625
  collectElements(addedNodes, addedElements);
611
626
  collectElements(removedNodes, removedElements);
@@ -615,21 +630,24 @@ function useAOSScope(options) {
615
630
  for (const element of addedElements) addAnimation(element);
616
631
  for (const element of updatedElements) updateAnimation(element);
617
632
  if (addedElements.size > 0 || removedElements.size > 0) {
618
- shouldRefresh.current = true;
633
+ shouldRefreshRef.current = true;
619
634
  }
620
635
  };
636
+ const updateScrollTrigger = () => {
637
+ if (!shouldRefreshRef.current || rafIdRef.current) return;
638
+ rafIdRef.current = requestAnimationFrame(() => {
639
+ ScrollTrigger.refresh();
640
+ shouldRefreshRef.current = false;
641
+ rafIdRef.current = 0;
642
+ });
643
+ };
621
644
  for (const element of gsap2.utils.toArray(
622
645
  AOS_SELECTORS,
623
646
  containerRef.current
624
647
  )) {
625
648
  addAnimation(element);
626
649
  }
627
- function updateScrollTrigger() {
628
- if (!shouldRefresh.current) return;
629
- ScrollTrigger.refresh();
630
- shouldRefresh.current = false;
631
- }
632
- window.addEventListener("scroll", updateScrollTrigger);
650
+ window.addEventListener("scroll", updateScrollTrigger, { passive: true });
633
651
  observerRef.current = new MutationObserver(handleMutation);
634
652
  observerRef.current.observe(containerRef.current, {
635
653
  childList: true,
@@ -652,7 +670,9 @@ function useAOSScope(options) {
652
670
  function collectElements(nodes, result) {
653
671
  for (const node of nodes) {
654
672
  if (!(node instanceof HTMLElement)) continue;
655
- if (node.matches(AOS_SELECTORS)) result.add(node);
673
+ if (node.hasAttribute(AOS_QUALIFIED_NAME)) {
674
+ result.add(node);
675
+ }
656
676
  for (const element of node.querySelectorAll(AOS_SELECTORS)) {
657
677
  result.add(element);
658
678
  }
@@ -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\n/** AOS 選擇器 */\nconst AOS_SELECTORS = \"[data-aos]\";\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 animationsWeakMap = useRef<WeakMap<HTMLElement, gsap.core.Tween>>(\n new WeakMap(),\n );\n const optionsRef = useRef(options);\n const shouldRefresh = useRef(false);\n\n // 使用靜態寫入,下次新增動畫才會套用覆蓋預設值\n useLayoutEffect(() => {\n optionsRef.current = options;\n }, [options]);\n\n useGSAP(\n (_, contextSafe) => {\n if (!containerRef.current || !contextSafe) return;\n\n /** 新增動畫 */\n const addAnimation = (element: HTMLElement) => {\n if (animationsWeakMap.current.has(element)) return;\n\n const newAnimation = contextSafe(createAnimation)(\n element,\n optionsRef.current,\n );\n if (!newAnimation) return;\n\n animationsWeakMap.current.set(element, newAnimation);\n };\n\n /** 移除動畫 */\n function removeAnimation(element: HTMLElement) {\n const animation = animationsWeakMap.current.get(element);\n if (!animation) return;\n\n animation.revert();\n animationsWeakMap.current.delete(element);\n }\n\n /** 更新動畫 */\n function 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 updatedElements.add(target);\n\n // 會影響觸發點的才開啟刷新\n if (\n attributeName === \"data-aos-anchor-placement\" ||\n attributeName === \"data-aos-offset\"\n ) {\n shouldRefresh.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 shouldRefresh.current = true;\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 /**\n * ScrollTrigger 刷新\n *\n * > `ScrollTrigger.refresh()` 會導致無限觸發滾動事件、攔截 `window.scroll`\n *\n * > MutationObserver 變化後才會重新開啟避免無限刷新\n * */\n function updateScrollTrigger() {\n if (!shouldRefresh.current) return;\n ScrollTrigger.refresh();\n shouldRefresh.current = false;\n }\n\n window.addEventListener(\"scroll\", updateScrollTrigger);\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 if (node.matches(AOS_SELECTORS)) result.add(node);\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/** 建立 ScrollTrigger 動畫 */\nfunction createScrollTriggerTween(\n element: HTMLElement,\n preset: AnimationPreset,\n vars: AnimationPreset,\n options?: Partial<AnimationOptions>,\n) {\n const { from, to } = vars;\n const { offset, delay, duration, easing, once, mirror, anchorPlacement } =\n mergeOptions(options);\n\n /** 上層基準容器 */\n const container = element.parentElement?.hasAttribute(\"data-aos-container\")\n ? element.parentElement\n : null;\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 / 1000,\n delay: delay / 1000,\n overwrite: \"auto\",\n scrollTrigger: {\n // markers: true,\n invalidateOnRefresh: true,\n trigger: container || 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,8 +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
- /** 刷新 AOS 動畫位置 */
5
- declare function refreshAOS(): void;
4
+ /** 原始 ScrollTrigger.refresh */
5
+ declare function refreshScrollTrigger(safe?: boolean | undefined): void;
6
6
 
7
7
  interface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {
8
8
  "data-aos": Animation;
@@ -13,4 +13,4 @@ interface AOSAttributeOptions extends Partial<AnimationOptions> {
13
13
  /** 將 options 轉成可直接使用的 AOS data attributes */
14
14
  declare function toAOSProps(options?: AOSAttributeOptions): Partial<AOSDataAttributes>;
15
15
 
16
- export { Animation, AnimationOptions, refreshAOS, toAOSProps };
16
+ export { Animation, AnimationOptions, refreshScrollTrigger, toAOSProps };
package/dist/index.d.ts CHANGED
@@ -1,8 +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
- /** 刷新 AOS 動畫位置 */
5
- declare function refreshAOS(): void;
4
+ /** 原始 ScrollTrigger.refresh */
5
+ declare function refreshScrollTrigger(safe?: boolean | undefined): void;
6
6
 
7
7
  interface AOSDataAttributes extends Partial<Record<AOSAttributeKey, string>> {
8
8
  "data-aos": Animation;
@@ -13,4 +13,4 @@ interface AOSAttributeOptions extends Partial<AnimationOptions> {
13
13
  /** 將 options 轉成可直接使用的 AOS data attributes */
14
14
  declare function toAOSProps(options?: AOSAttributeOptions): Partial<AOSDataAttributes>;
15
15
 
16
- export { Animation, AnimationOptions, refreshAOS, toAOSProps };
16
+ export { Animation, AnimationOptions, refreshScrollTrigger, toAOSProps };
package/dist/index.js CHANGED
@@ -30,17 +30,17 @@ 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,
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
- function refreshAOS() {
43
- import_ScrollTrigger.ScrollTrigger.refresh(true);
42
+ function refreshScrollTrigger(safe) {
43
+ import_ScrollTrigger.ScrollTrigger.refresh(safe);
44
44
  }
45
45
 
46
46
  // src/animation/constants.ts
@@ -113,7 +113,8 @@ function toAOSProps(options) {
113
113
  "data-aos-anchor-placement": validateEnumValue(
114
114
  anchorPlacements,
115
115
  options.anchorPlacement
116
- )
116
+ ),
117
+ "data-aos-markers": toBooleanAttr(options.markers)
117
118
  });
118
119
  }
119
120
  function omitNil(obj) {
@@ -139,7 +140,7 @@ function validateEnumValue(list, value) {
139
140
  }
140
141
  // Annotate the CommonJS export names for ESM import in node:
141
142
  0 && (module.exports = {
142
- refreshAOS,
143
+ refreshScrollTrigger,
143
144
  toAOSProps
144
145
  });
145
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/** 刷新 AOS 動畫位置 */\nexport default function refreshAOS() {\n ScrollTrigger.refresh(true);\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\";\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;AAGlB,SAAR,aAA8B;AACnC,qCAAc,QAAQ,IAAI;AAC5B;;;ACMO,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,9 @@
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
- function refreshAOS() {
6
- ScrollTrigger.refresh(true);
5
+ function refreshScrollTrigger(safe) {
6
+ ScrollTrigger.refresh(safe);
7
7
  }
8
8
 
9
9
  // src/animation/constants.ts
@@ -76,7 +76,8 @@ function toAOSProps(options) {
76
76
  "data-aos-anchor-placement": validateEnumValue(
77
77
  anchorPlacements,
78
78
  options.anchorPlacement
79
- )
79
+ ),
80
+ "data-aos-markers": toBooleanAttr(options.markers)
80
81
  });
81
82
  }
82
83
  function omitNil(obj) {
@@ -101,7 +102,7 @@ function validateEnumValue(list, value) {
101
102
  return list.includes(value) ? value : void 0;
102
103
  }
103
104
  export {
104
- refreshAOS,
105
+ refreshScrollTrigger,
105
106
  toAOSProps
106
107
  };
107
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/** 刷新 AOS 動畫位置 */\nexport default function refreshAOS() {\n ScrollTrigger.refresh(true);\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\";\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;AAGlB,SAAR,aAA8B;AACnC,gBAAc,QAAQ,IAAI;AAC5B;;;ACMO,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.2.2",
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",