如何实现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
相关产品推荐
相关产品推荐

