Appearance
AnimationService
Manages keyframe animations and engine-based tweens for Three.js objects. The service owns the SDK-facing API; the lower-level tween/timeline runtime lives in AnimationEngine.
Access
Registered under the name "animation". No service dependencies.
AnimationService is not exported from the SDK entry point. Reach it by its registered name and use the class only as a type.
ts
import type { AnimationService } from "@optellix/xviewr-sdk";
await viewer.ready();
const anim = viewer.getService<AnimationService>("animation");Public API
Lifecycle
init(context: ServiceContext): Promise<void>destroy(): Promise<void>getStatus(): ServiceStatus
Keyframe Animations
createAnimation(config: AnimationConfig): Animation- creates and registers a keyframe animation. Does not start it.playAnimation(id: string): boolean- starts playback from the current time.stopAnimation(id: string): boolean- stops and resets current time to 0.pauseAnimation(id: string): boolean- pauses at the current time.resumeAnimation(id: string): boolean- resumes a paused animation. Returnsfalseif already completed.setAnimationTime(id: string, time: number): boolean- seeks to a specific time and applies the interpolated value immediately.getAnimation(id: string): Animation | nullremoveAnimation(id: string): boolean- stops and removes the animation.
Timelines
createTimeline(config: TimelineConfig): TimelineaddTrackToTimeline(timelineId: string, track: Track): booleanplayTimeline(id: string): booleanstopTimeline(id: string): boolean
Global Controls
pauseAll(): void- pauses the service clock; no keyframe animations advance untilresumeAll.resumeAll(): voidstopAllAnimations(): void- stops keyframe animations and engine tweens/timelines.setTimeScale(scale: number): void- multiplies delta time for keyframe animations.0freezes,2doubles speed.update(): void- advances active keyframe animations by one frame. The engine tween layer runs on its own RAF ticker.
Engine Helpers
animateWithEngine(target: any, properties: Record<string, any>, duration: number, options?: AnimationTweenVars): AnimationTweenanimateVector3(target: any, property: string, toValue: THREE.Vector3, duration?: number, options?: AnimationTweenVars): AnimationTween- animates aVector3property.animateProperties(target: any, properties: Record<string, any>, duration?: number, options?: AnimationTweenVars): AnimationTween- animates numeric properties, including dot-paths like"rotation.x".createEngineTimeline(id: string, options?: AnimationTimelineVars): AnimationTimeline- creates and registers a named engine timeline.stopEngineTimeline(id: string): booleanstopAllEngineAnimations(): void
Transform Helpers
animateProperty(target: any, property: string, from: any, to: any, duration: number, options?: Partial<AnimationConfig>): AnimationanimateTransform(object: THREE.Object3D, transforms: TransformKeyframe[], duration: number, options?: Partial<AnimationConfig>): Animation[]animateTransformWithEngine(objects: THREE.Object3D[], startTransforms, endTransforms, duration: number, options?: AnimationTimelineVars): AnimationTimeline
Camera State Helpers
getOrbitState(controls: any, camera: THREE.Camera): CameraTransformapplyOrbitState(controls: any, camera: THREE.Camera, state: CameraTransform): void
Engine Runtime
AnimationEngine provides AnimationTween and AnimationTimeline. Tweens support:
kill(),pause(),play(),restart(),progress(), andisActive()eventCallback("onStart" | "onUpdate" | "onComplete" | "onInterrupt", callback)linear,none, andpower1throughpower4easing modes with.in,.out, and.inOut
Types
ts
interface AnimationConfig {
id?: string;
name?: string;
target: any;
property: string;
keyframes: Keyframe[];
duration: number;
loop?: boolean;
easing?: EasingFunction;
onUpdate?: (animation: Animation) => void;
onComplete?: (animation: Animation) => void;
}
interface Keyframe {
time: number;
value: any;
}
interface TimelineConfig {
id?: string;
name?: string;
loop?: boolean;
onUpdate?: (timeline: Timeline) => void;
onComplete?: (timeline: Timeline) => void;
}
interface Track {
id?: string;
name: string;
startTime: number;
duration: number;
animation: Animation;
}
interface TransformKeyframe {
time: number;
position?: THREE.Vector3;
rotation?: THREE.Euler;
scale?: THREE.Vector3;
}
interface CameraTransform {
target: { x: number; y: number; z: number };
theta: number;
phi: number;
radius: number;
zoom: number;
fov?: number;
}
type EasingFunction = "linear" | "easeIn" | "easeOut" | "easeInOut";Keyframe interpolation supports number, THREE.Vector3, THREE.Euler, and THREE.Color. Other types fall back to the start value.
Events
| Event | Payload |
|---|---|
animation:created | { animation: Animation } |
animation:started | { animation: Animation } |
animation:stopped | { animation: Animation } |
animation:paused | { animation: Animation } |
animation:resumed | { animation: Animation } |
animation:completed | { animation: Animation } |
animation:removed | { id: string } |
animation:all-paused | null |
animation:all-resumed | null |
animation:timescale-changed | { scale: number } |
animation:tween-started | { target: any; properties: any } |
animation:tween-completed | { target: any; properties: any } |
animation:timeline-engine-started | { id: string } |
animation:timeline-engine-completed | { id: string } |
timeline:created | { timeline: Timeline } |
timeline:started | { timeline: Timeline } |
timeline:stopped | { timeline: Timeline } |
timeline:completed | { timeline: Timeline } |
timeline:track-added | { timeline: Timeline; track: Track } |
Example
ts
const anim = viewer.getService<AnimationService>("animation");
if (!anim) return;
const mesh = viewer.getService("mesh")?.getById("part-001");
const fly = anim.createAnimation({
target: mesh,
property: "position.y",
keyframes: [
{ time: 0, value: 0 },
{ time: 1.5, value: 10 },
{ time: 3, value: 0 },
],
duration: 3,
loop: true,
easing: "easeInOut",
});
anim.playAnimation(fly.id);
const camera = viewer.getService("camera");
anim.animateVector3(
camera?.getCamera(),
"position",
new THREE.Vector3(50, 30, 80),
2.5,
{ ease: "power2.out" }
);
anim.setTimeScale(0.5);