@web-engine-dev/animation
Animation system with skeletal animation, blending, state machines, and inverse kinematics for web-engine-dev.
Features
- Skeletal Animation: Bone-based character animation
- Animation Blending: Smooth transitions between animations
- State Machines: Visual animation state management
- Inverse Kinematics (IK): Procedural bone positioning
- Animation Clips: Keyframe-based animation data
- Blend Trees: Complex animation mixing
Installation
bash
npm install @web-engine-dev/animation
# or
pnpm add @web-engine-dev/animationQuick Start
typescript
import {
AnimationClip,
AnimationController,
Skeleton,
AnimationStateMachine,
} from '@web-engine-dev/animation';
// Load skeleton and animations
const skeleton = loadSkeleton(characterModel);
const walkClip = loadAnimation('walk.anim');
// Create controller with a base layer
const controller = new AnimationController({ skeleton });
controller.playOnLayer('base', walkClip);
// Update each frame
controller.update(deltaTime);
controller.applyPose();API Overview
Animation Clips
typescript
const clip = new AnimationClip({
name: 'walk',
duration: 1.0,
loopMode: 'loop',
tracks: [
{ boneName: 'hip', keyframes: [...] },
{ boneName: 'leg_l', keyframes: [...] },
],
});
clip.sample(time); // Get track samples at timeAnimation Controller
typescript
const controller = new AnimationController({
skeleton,
layers: [{ name: 'base', weight: 1, blendMode: 'override' }],
});
controller.playOnLayer('base', walkClip, { blendTime: 0.2 });
controller.update(deltaTime);
controller.applyPose();State Machine
typescript
const stateMachine = new AnimationStateMachine(skeleton.boneCount);
stateMachine.addState({ name: 'idle', type: 'clip', clip: idleClip });
stateMachine.addState({ name: 'walk', type: 'clip', clip: walkClip });
stateMachine.addState({ name: 'run', type: 'clip', clip: runClip });
stateMachine.addTransition({
fromState: 'idle',
toState: 'walk',
conditions: [{ parameter: 'speed', operator: 'greater', value: 0 }],
duration: 0.3,
});Track Sample Appliers (Custom Properties)
typescript
import { AnimationController, type TrackSampleApplier } from '@web-engine-dev/animation';
const trackApplier: TrackSampleApplier = (track, sample) => {
if (track.targetProperty === 'weights') {
applyMorphWeights(track.targetPath, sample as number[]);
}
};
const controller = new AnimationController({ skeleton }, trackApplier);Inverse Kinematics
typescript
const ik = new IKSolver(skeleton);
// Set IK target for hand
ik.setTarget('hand_r', targetPosition);
// Solve IK chain
ik.solve();Peer Dependencies
@web-engine-dev/math- Vector/quaternion math