如何使用新版Framer Motion为React Three Fiber Group对象添加动画?
解决React Three Fiber中Group组件的Framer Motion动画问题
针对新版Framer Motion不再支持framer-motion-3d的情况,你可以通过framer-motion/three模块为R3F的Group组件添加动画,具体步骤如下:
1. 导入正确的Motion组件
从framer-motion/three中导入motion,它专门用于Three.js元素的动画,而非framer-motion或framer-motion/dom模块。
2. 创建可动画的Group
直接使用framer-motion/three提供的motion.group(新版已封装对应Three.js原生对象的motion组件),或用motion()包裹R3F的Group组件,生成支持动画的版本。
3. 定义动画Variants
按照原需求定义状态变体,示例如下:
const pageVariants = { hidden: { y: -5 }, visible: { y: 0, transition: { duration: 0.6, ease: "easeInOut" } } };
4. 在组件中应用动画
将页面元素放入可动画的Group中,根据当前页面激活状态,绑定animate属性到对应变体状态。
修改后的Experience.jsx示例代码
import { Canvas } from "@react-three/fiber"; import { motion } from "framer-motion/three"; import { useState } from "react"; // 定义动画变体 const pageVariants = { hidden: { y: -5 }, visible: { y: 0, transition: { duration: 0.6, ease: "easeInOut" } } }; const PageSection = ({ isActive, children }) => { return ( <motion.group variants={pageVariants} initial="hidden" animate={isActive ? "visible" : "hidden"} > {children} </motion.group> ); }; export default function Experience() { // 模拟页面激活状态,实际可根据滚动/路由逻辑修改 const [activePage, setActivePage] = useState(0); return ( <Canvas> <ambientLight intensity={0.5} /> <directionalLight position={[5, 5, 5]} /> {/* 第一页内容 */} <PageSection isActive={activePage === 0}> <mesh position={[0, 0, 0]}> <boxGeometry args={[2, 2, 2]} /> <meshStandardMaterial color="crimson" /> </mesh> </PageSection> {/* 第二页内容 */} <PageSection isActive={activePage === 1}> <mesh position={[0, 0, 0]}> <sphereGeometry args={[1.5, 32, 32]} /> <meshStandardMaterial color="deepskyblue" /> </mesh> </PageSection> {/* 模拟页面切换控件(实际项目替换为滚动/路由逻辑) */} <primitive object={document.getElementById("page-switcher")} /> </Canvas> ); }
关键注意事项
- 确保安装最新版
framer-motion与@react-three/fiber,版本不兼容可能引发异常。 - 动画属性必须是Three.js对象支持的属性(如
position.y),不可使用DOM元素属性。 - 若需滚动触发动画,可结合
framer-motion的useScroll钩子或第三方滚动监听库,根据滚动位置更新activePage状态。
内容的提问来源于stack exchange,提问作者Veron
相关产品推荐
相关产品推荐

