react-three-fiber中用GSAP实现RingBufferGeometry的thetaLength定点停止动画
RingBufferGeometry动画实现说明
需求描述
- 使用GSAP驱动动画,在指定时长内对RingBufferGeometry的thetaLength属性做插值动画,不使用Math.sin()实现动效
- thetaLength达到预设目标值后自动停止动画,最终呈现完整的三角形环形形态
实现问题修正
原有代码无法正常触发动画是因为Three.js的RingBufferGeometry初始化后,直接修改parameters参数不会触发几何体更新,且useEffect未添加依赖数组会导致动画重复执行。
完整实现代码
入口文件
import React from 'react' import ReactDOM from 'react-dom' import App from './App' function Container(props) { return <div style={{ position: 'absolute', inset: 0 }} {...props} /> } ReactDOM.render( <Container> <App /> </Container>, document.getElementById('root') )
业务逻辑文件
import { useRef, useEffect, useState } from 'react' import { Canvas } from '@react-three/fiber' import { OrbitControls } from '@react-three/drei' import * as THREE from 'three' import gsap from 'gsap' export default function App() { return ( <Canvas camera={{ position: [0, 0, 15] }}> <color attach="background" args={['black']} /> <OrbitControls /> <spotLight position={[15, 15, 15]} angle={0.3} color={'white'} /> <TriangleRing /> </Canvas> ) } const TriangleRing = () => { const [thetaLength, setThetaLength] = useState(0) const parametersObj = { innerRadius: 4, outerRadius: 8, thetaSegments: 3, phiSegments: 30, thetaStart: Math.PI / 2, } useEffect(() => { const animationObj = { thetaLength: 0 } const tl = gsap.timeline({ defaults: { ease: 'power3.inOut' } }) tl.to(animationObj, { thetaLength: (Math.PI * 2) / 3, duration: 4, onUpdate: () => { setThetaLength(animationObj.thetaLength) } }) }, []) const parameters = [ parametersObj.innerRadius, parametersObj.outerRadius, parametersObj.thetaSegments, parametersObj.phiSegments, parametersObj.thetaStart, thetaLength, ] return ( <mesh> <ringBufferGeometry args={parameters} key={thetaLength} name="TriangleRing" /> <meshToonMaterial side={THREE.DoubleSide} color={0xffffff} /> </mesh> ) }
核心修改说明
- 新增useState存储thetaLength状态,配合ringBufferGeometry的key属性,当thetaLength更新时React Three Fiber会自动重新实例化几何体
- GSAP插值普通对象的thetaLength属性,在onUpdate回调中同步更新状态触发重绘
- useEffect添加空依赖数组,保证动画仅在组件挂载时执行一次
- 调整thetaSegments为3、thetaLength目标值为2π/3,实现完整的三角形环形形态
内容的提问来源于stack exchange,提问作者pk35621
相关产品推荐
相关产品推荐

