TkAstral3D/packages/sdk/lib/core/script/Animation.ts
2025-10-04 23:36:07 +08:00

111 lines
3.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {Object3D, AnimationAction,LoopOnce, LoopRepeat, LoopPingPong} from "three";
import type {AnimationActionLoopStyles} from "three";
export class Animation {
object:Object3D;
actionsMap:Map<string, AnimationAction>;
lastPlayAction:AnimationAction | undefined;
// 整个动作过程动画剪辑AnimationClip执行的次数
repetitions:number = Infinity;
static ActionLoop = {
LoopOnce: LoopOnce,
LoopRepeat: LoopRepeat,
LoopPingPong: LoopPingPong,
}
constructor(object:Object3D) {
this.object = object;
this.actionsMap = this.getActionsMap();
}
/**
* 获取对象的AnimationActions。
* @returns AnimationAction Map.
*/
getActionsMap():Map<string, AnimationAction> {
const actionsMap = new Map<string, AnimationAction>();
const animations = this.object.animations as unknown as AnimationAction[];
if (animations.length > 0) {
for (let animation of animations ) {
actionsMap.set(animation.getClip().name, animation);
}
}
return actionsMap;
}
/**
* 返回 AnimationAction用于用户直接调用AnimationAction的方法。
* AnimationAction 文档https://threejs.org/docs/index.html#api/zh/animation/AnimationAction
* @param name 动画名称。
* @returns AnimationAction | undefined
*/
getAction(name:string):AnimationAction | undefined {
return this.actionsMap.get(name);
}
get actions():AnimationAction[] {
return Array.from(this.actionsMap.values());
}
/**
* 播放动画,支持链式调用
*/
play(name:string, loop:AnimationActionLoopStyles = Animation.ActionLoop.LoopRepeat, timeScale:number = 1):Animation {
const action = this.actionsMap.get(name);
if (action) {
action.paused = false;
action.repetitions = this.repetitions;
action.loop = loop;
action.timeScale = timeScale;
action.play();
this.lastPlayAction = action;
}
return this;
}
/**
* 暂停动画,支持链式调用
*/
pause(name:string | undefined):Animation {
if(name === undefined){
this.lastPlayAction && (this.lastPlayAction.paused = true);
return this;
}
const action = this.actionsMap.get(name);
if (action) {
action.paused = true;
}
return this;
}
/**
* 停止动画,支持链式调用
*/
stop(name:string | undefined):Animation {
if (name === undefined) {
this.lastPlayAction &&this.lastPlayAction.stop();
this.lastPlayAction = undefined;
return this;
}
const action = this.actionsMap.get(name);
if (action) {
action.stop();
}
if (this.lastPlayAction === action) {
this.lastPlayAction = undefined;
}
return this;
}
}