ReactPixi中实现Sprite平滑移动动画的方法咨询
实现React-Pixi Sprite平滑移动动画的方案
1. 用Pixi官方补间库(最推荐)
Pixi有官方的@pixi/tween库,能像CSS过渡一样给x、y、rotation等属性加平滑动画,完全匹配你的需求。
操作步骤:
- 先安装依赖:
npm install @pixi/tween
- 组件中实现代码:
import { Stage, Sprite } from '@pixi/react'; import { Tween, TweenManager } from '@pixi/tween'; import { useEffect, useRef } from 'react'; // 全局初始化补间管理器 const tweenManager = new TweenManager(); export default function AnimatedSpriteDemo({ size }) { const spriteRef = useRef(null); useEffect(() => { if (!spriteRef.current) return; const sprite = spriteRef.current; // 设置初始位置(比如从下方进入,初始y设为画布高度) sprite.y = size.width; // 创建补间:1秒内移动到y=0的位置 const tween = new Tween(sprite) .to({ y: 0 }, 1000) .ease('easeOutQuad') // 缓动函数,对应CSS的transition-timing-function效果 .start(); tweenManager.add(tween); // 组件卸载时清理动画 return () => { tween.stop(); tweenManager.remove(tween); }; }, [size]); return ( <Stage width={size.width} height={size.width * (1597 / 2486)}> <Sprite ref={spriteRef} image='img/parallax/fog_1.png' x={0} width={size.width} height={size.width} /> </Stage> ); }
要实现部分Sprite向上、部分向下,只要给不同Sprite设置不同的初始位置和目标位置即可——比如一个初始y设为-size.width(从上方进入),目标y=0;另一个初始y设为size.width(从下方进入),目标y=0。
2. 用React状态+requestAnimationFrame(无额外依赖)
不想装库的话,可以手动用React状态结合原生requestAnimationFrame实现:
import { Stage, Sprite } from '@pixi/react'; import { useEffect, useState, useRef } from 'react'; export default function AnimatedSpriteDemo({ size }) { const [spriteY, setSpriteY] = useState(size.width); // 初始y位置 const animationRef = useRef(null); const startTimeRef = useRef(null); const duration = 1000; // 动画时长1秒 useEffect(() => { const animate = (timestamp) => { if (!startTimeRef.current) startTimeRef.current = timestamp; const elapsed = timestamp - startTimeRef.current; const progress = Math.min(elapsed / duration, 1); // 手动实现easeOutQuad缓动效果 const easedProgress = 1 - Math.pow(1 - progress, 2); // 计算当前y值:初始位置 + (目标位置-初始位置)*进度 setSpriteY(size.width - size.width * easedProgress); if (progress < 1) { animationRef.current = requestAnimationFrame(animate); } }; animationRef.current = requestAnimationFrame(animate); return () => { animationRef.current && cancelAnimationFrame(animationRef.current); }; }, [size]); return ( <Stage width={size.width} height={size.width * (1597 / 2486)}> <Sprite image='img/parallax/fog_1.png' x={0} y={spriteY} width={size.width} height={size.width} /> </Stage> ); }
这种方法适合简单场景,复杂动画还是用补间库更省心。
3. 用react-spring结合React-Pixi
如果你熟悉react-spring,也可以用它实现属性过渡:
- 先安装依赖:
npm install react-spring @react-spring/web @react-spring/pixi
- 组件代码:
import { Stage, Sprite } from '@pixi/react'; import { useSpring } from '@react-spring/pixi'; export default function AnimatedSpriteDemo({ size }) { // 创建动画属性:从y=size.width移动到y=0,时长1秒 const props = useSpring({ y: 0, from: { y: size.width }, config: { duration: 1000, easing: (t) => 1 - Math.pow(1 - t, 2) } }); return ( <Stage width={size.width} height={size.width * (1597 / 2486)}> <Sprite image='img/parallax/fog_1.png' x={0} width={size.width} height={size.width} {...props} // 把动画属性传递给Sprite /> </Stage> ); }
关键注意事项
- 别在render里硬编码属性变化,要通过状态或补间库控制,保证动画流畅。
- 缓动函数能让动画更自然,常见的
easeInQuad、easeOutQuad等,补间库和react-spring都内置了这些效果。 - 多个Sprite的独立动画,只要给每个Sprite设置各自的初始位置、目标位置和时长即可。
内容的提问来源于stack exchange,提问作者Jakub Hampl
相关产品推荐
相关产品推荐

