You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:25:54