Template
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
30 lines
982 B
TypeScript
30 lines
982 B
TypeScript
import { useGSAP } from "@gsap/react";
|
|
import { gsap } from "gsap";
|
|
import { useEffect, useState } from "react";
|
|
|
|
// GSAP 仅用于时间轴编排、播放控制和 CSS 难以清晰表达的课件动画。
|
|
// 普通状态过渡、hover 和简单入场动画优先使用 CSS/Tailwind。
|
|
gsap.registerPlugin(useGSAP);
|
|
|
|
// 项目统一缓动,对齐现有 CSS cubic-bezier(0.16, 1, 0.3, 1)
|
|
export const EASE_OUT = "power3.out";
|
|
export const EASE_IN_OUT = "power2.inOut";
|
|
|
|
export { gsap, useGSAP };
|
|
|
|
// 响应 prefers-reduced-motion,供动画降级
|
|
export function useReducedMotion(): boolean {
|
|
const [reduced, setReduced] = useState(
|
|
() => window.matchMedia("(prefers-reduced-motion: reduce)").matches,
|
|
);
|
|
|
|
useEffect(() => {
|
|
const mql = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
const onChange = () => setReduced(mql.matches);
|
|
mql.addEventListener("change", onChange);
|
|
return () => mql.removeEventListener("change", onChange);
|
|
}, []);
|
|
|
|
return reduced;
|
|
}
|