NextJS + framer-motion:如何让动画仅初始加载触发且每12小时重置?
解决方案
1. 完全可以用动画结束回调
framer-motion 的 motion.div 原生支持 onAnimationComplete 回调函数,会在元素的所有动画序列执行完毕后触发,刚好满足你在动画结束后设置 localStorage 的需求。
2. 结合 NextJS 实现仅首次加载动画的完整代码示例
import { motion } from "framer-motion"; import { useState, useEffect } from "react"; export default function Home() { // 控制是否播放加载动画 const [playAnimation, setPlayAnimation] = useState(false); useEffect(() => { // 客户端渲染阶段读取 localStorage,判断是否已看过动画 const hasSeenIntro = localStorage.getItem("hasSeenIntro"); if (!hasSeenIntro) { setPlayAnimation(true); } }, []); // 动画完成后设置标记 const handleAnimationFinish = () => { localStorage.setItem("hasSeenIntro", "true"); setPlayAnimation(false); }; return ( <div className="home-wrapper"> {playAnimation ? ( <motion.div initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 1, ease: "easeOut" }} onAnimationComplete={handleAnimationFinish} > {/* 这里放你的加载动画内容,比如logo、文字动效 */} <div className="loading-animation"> <h1>加载中...</h1> </div> </motion.div> ) : ( <div className="home-content"> {/* 主页正常展示内容 */} <h1>我的主页</h1> {/* 其他页面内容 */} </div> )} </div> ); }
关键细节说明
- 由于 NextJS 存在 SSR 渲染,
localStorage只能在客户端环境访问,所以必须把读取逻辑放在useEffect钩子中(该钩子仅在客户端首次渲染后执行) onAnimationComplete会等待当前 motion 元素的所有动画(包括序列动画、嵌套动画)全部结束后才触发,确保标记是在动画真正完成后设置的- 如果后续需要重置这个标记(比如测试需求),可以在浏览器控制台执行
localStorage.removeItem("hasSeenIntro")清除记录
内容的提问来源于stack exchange,提问作者hanss
相关产品推荐
相关产品推荐

