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