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

如何实现onPointerLeave时动画播放至最后一帧再停止?

解决方案

要实现鼠标离开后动画播放至最后一帧再停止,核心是不直接在鼠标离开时暂停动画,而是让动画自然播放到结束后再停止,同时保证动画结束后停留在最后一帧。以下是针对你代码的具体修改方案:

修改后的代码

import { useState, useEffect } from 'react';
import * as THREE from 'three';

// 组件内部逻辑
const [stopAfterFinish, setStopAfterFinish] = useState(false);
const pencilAnim = actions["UX-penceil-item_anim"];

useEffect(() => {
  if (!pencilAnim) return;

  // 动画结束时的处理逻辑
  const handleAnimFinish = () => {
    if (stopAfterFinish) {
      pencilAnim.paused = true;
      setStopAfterFinish(false);
    }
  };

  // 设置动画结束后停在最后一帧,不跳回起始帧
  pencilAnim.clampWhenFinished = true;
  // 监听动画结束事件
  pencilAnim.addEventListener('finished', handleAnimFinish);

  // 组件卸载时移除监听
  return () => {
    pencilAnim.removeEventListener('finished', handleAnimFinish);
  };
}, [pencilAnim, stopAfterFinish]);

// 渲染mesh部分
<mesh
    name="rond-ui-item-01"
    geometry={nodes["rond-ui-item-01"].geometry}
    material={materials["Material.019"]}
    position={[-4.194373, 6.492984, 18.510574]}
    rotation={[0, 0, -Math.PI / 2]}
    scale={1.096397}
    onPointerOver={() => {
        // 鼠标悬停时:取消停止标记,恢复循环播放,启动动画
        setStopAfterFinish(false);
        pencilAnim.setLoop(THREE.LoopRepeat);
        pencilAnim.paused = false;
        pencilAnim.play();
    }}
    onPointerLeave={() => {
        // 鼠标离开时:标记需要在结束后停止,设置动画为单次播放(播放至当前循环结束)
        setStopAfterFinish(true);
        pencilAnim.setLoop(THREE.LoopOnce);
    }}
/>

关键细节说明

  • clampWhenFinished = true:强制动画播放到最后一帧后停留在该帧,避免默认的跳回起始帧行为。
  • setLoop(THREE.LoopOnce):鼠标离开时将动画改为单次播放模式,让当前正在播放的动画片段完整播放完毕。
  • 动画finished事件监听:在动画自然结束后,根据之前的标记判断是否需要暂停动画,实现“播放至最后一帧再停止”的需求。

内容的提问来源于stack exchange,提问作者user18514215

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:01:35