"use client" import { useState, useEffect, useRef, useCallback } from "react" /** * 监听滚动位置,返回 scrollY 值(被动监听,高性能) */ export function useScrollY() { const [scrollY, setScrollY] = useState(0) useEffect(() => { const onScroll = () => setScrollY(window.scrollY) window.addEventListener("scroll", onScroll, { passive: true }) return () => window.removeEventListener("scroll", onScroll) }, []) return scrollY } /** * 对给定元素计算视差偏移量 * @param speed 视差倍率,0 = 无效果,0.5 = 半速(向上),负值反向 * @returns ref + translateY 字符串 */ export function useParallax(speed: number = 0.4) { const ref = useRef(null) const [offset, setOffset] = useState(0) const calculate = useCallback(() => { if (!ref.current) return const rect = ref.current.getBoundingClientRect() const centerY = rect.top + rect.height / 2 const viewportCenter = window.innerHeight / 2 setOffset((centerY - viewportCenter) * speed) }, [speed]) useEffect(() => { calculate() window.addEventListener("scroll", calculate, { passive: true }) window.addEventListener("resize", calculate, { passive: true }) return () => { window.removeEventListener("scroll", calculate) window.removeEventListener("resize", calculate) } }, [calculate]) return { ref, translateY: `${offset}px` } }