Skip to content

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. Returns false if already completed.
  • setAnimationTime(id: string, time: number): boolean - seeks to a specific time and applies the interpolated value immediately.
  • getAnimation(id: string): Animation | null
  • removeAnimation(id: string): boolean - stops and removes the animation.

Timelines ​

  • createTimeline(config: TimelineConfig): Timeline
  • addTrackToTimeline(timelineId: string, track: Track): boolean
  • playTimeline(id: string): boolean
  • stopTimeline(id: string): boolean

Global Controls ​

  • pauseAll(): void - pauses the service clock; no keyframe animations advance until resumeAll.
  • resumeAll(): void
  • stopAllAnimations(): void - stops keyframe animations and engine tweens/timelines.
  • setTimeScale(scale: number): void - multiplies delta time for keyframe animations. 0 freezes, 2 doubles 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): AnimationTween
  • animateVector3(target: any, property: string, toValue: THREE.Vector3, duration?: number, options?: AnimationTweenVars): AnimationTween - animates a Vector3 property.
  • 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): boolean
  • stopAllEngineAnimations(): void

Transform Helpers ​

  • animateProperty(target: any, property: string, from: any, to: any, duration: number, options?: Partial<AnimationConfig>): Animation
  • animateTransform(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): CameraTransform
  • applyOrbitState(controls: any, camera: THREE.Camera, state: CameraTransform): void

Engine Runtime ​

AnimationEngine provides AnimationTween and AnimationTimeline. Tweens support:

  • kill(), pause(), play(), restart(), progress(), and isActive()
  • eventCallback("onStart" | "onUpdate" | "onComplete" | "onInterrupt", callback)
  • linear, none, and power1 through power4 easing 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 ​

EventPayload
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-pausednull
animation:all-resumednull
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);

XViewr SDK and xConvert CLI documentation.