Skip to content

AnimationPlugin

Wrapper around AnimationService for tween/timeline playback, plus scene-state capture/restore and delta animation between snapshots.

Usage

ts
const viewer = new ViewerCore(container, {
  plugins: [{ name: "animation", enabled: true }],
});
await viewer.ready();

const anim = viewer.pluginManager.getPlugin("animation") as AnimationPlugin;

Or:

ts
await viewer.loadPlugin(new AnimationPlugin());

Service dependency: animation. The plugin starts its own requestAnimationFrame loop on activate and stops it on deactivate.

Public API

Tween/timeline forwarders

These delegate directly to AnimationService:

createAnimation, playAnimation, stopAnimation, pauseAnimation, resumeAnimation, setAnimationTime, getAnimation, removeAnimation, createTimeline, addTrackToTimeline, playTimeline, stopTimeline, pauseAll, resumeAll, stopAllAnimations, setTimeScale, animateProperty, animateTransform.

See AnimationService for parameter shapes.

Scene state

MethodDescription
captureSceneState(options?)Walk viewer.root, snapshot every object with an xvId. Returns a SceneStateSnapshot.
restoreSceneState(snapshot, options?)Apply a snapshot to the current scene. Objects are matched by xvId. Calls viewer.render().
animateSceneStateDelta(from, to, options?)Interpolate between two snapshots. Restores from first unless restoreFromState: false.
animateDelta(fromObject, toObject, options?)Same as above but takes Object3D trees rather than snapshots.
captureCameraState(sceneRoot, camera, controls)Stash a camera state on sceneRoot.userData.cameraState for later replay.

Types

ts
interface SceneObjectState {
  id: string;
  name?: string;
  position: { x: number; y: number; z: number };
  rotation: { x: number; y: number; z: number };
  scale: { x: number; y: number; z: number };
  visible: boolean;
}

interface SceneStateSnapshot {
  id: string;
  createdAt: number;
  objects: SceneObjectState[];
  camera?: CameraTransform & { position: Vector3; rotation: Vector3 };
}

interface SceneStateCaptureOptions {
  includeCamera?: boolean;                                  // default true
  filter?: (object: THREE.Object3D) => boolean;
}

interface SceneStateRestoreOptions {
  includeCamera?: boolean;                                  // default true
}

interface DeltaAnimationOptions {
  duration?: number;                                        // seconds, default 1.0
  mode?: "simultaneous" | "sequential";                     // default "simultaneous"
  sequentialDelay?: number;                                 // seconds, default 0.1
  properties?: Array<"position" | "rotation" | "scale" | "visibility" | "camera">;
  filter?: (object: THREE.Object3D) => boolean;
  camera?: THREE.Camera;
  controls?: any;
}

interface SceneStateDeltaOptions extends DeltaAnimationOptions {
  restoreFromState?: boolean;                               // default true
}

Scene capture/restore is keyed by object.userData.xv.xvId. Objects without an xvId are skipped.

Example

ts
const anim = viewer.pluginManager.getPlugin("animation") as AnimationPlugin;

const before = anim.captureSceneState({ includeCamera: true });

// User edits the scene...

const after = anim.captureSceneState();

await anim.animateSceneStateDelta(before, after, {
  duration: 1.5,
  mode: "simultaneous",
  properties: ["position", "rotation", "visibility"],
});

XViewr SDK and xConvert CLI documentation.