@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
159 lines (158 loc) • 9.08 kB
TypeScript
import { AnimationClip, Color, Euler, Object3D, Quaternion, Vector3 } from "three";
import type { Light, Material, PerspectiveCamera } from "three";
/** A Vector3 value, either as a Three.js Vector3 or as a `[x, y, z]` tuple */
export type Vec3Value = Vector3 | [number, number, number];
/** A Quaternion value, either as a Three.js Quaternion or as a `[x, y, z, w]` tuple */
export type QuatValue = Quaternion | [number, number, number, number];
/** A Color value, either as a Three.js Color or as an `[r, g, b]` tuple (0–1) */
export type ColorValue = Color | [number, number, number];
/** An Euler value, either as a Three.js Euler or as a `[x, y, z]` tuple (radians) */
export type EulerValue = Euler | [number, number, number];
/** User-friendly interpolation mode names */
export type AnimationInterpolation = "linear" | "smooth" | "step";
/** A single keyframe: a time and a value */
export type AnimationKeyframe<V> = {
/** Time in seconds */
time: number;
/** The value at this time */
value: V;
/** Interpolation mode for this track (default: `"linear"`). Note: Three.js applies one mode per track; the first keyframe's mode is used. */
interpolation?: AnimationInterpolation;
};
/** Shorthand for a simple two-keyframe animation (start → end) */
export type Tween<V> = {
/** Start value (at time 0) */
from: V;
/** End value (at time = duration) */
to: V;
/** Duration in seconds (default: 1) */
duration?: number;
/** Interpolation mode (default: `"linear"`) */
interpolation?: AnimationInterpolation;
};
/** Keyframe array or tween shorthand */
type KF<V> = AnimationKeyframe<V>[] | Tween<V>;
/**
* An opaque descriptor for a single animation track.
* Created by {@link track} and resolved into a Three.js KeyframeTrack
* when passed to {@link createAnimation}, or inline to
* {@link AnimatorControllerBuilder.state} / {@link TimelineBuilder.clip}.
*
* @category Animation and Sequencing
*/
export type TrackDescriptor = {
readonly __isTrackDescriptor: true;
/** @internal */ readonly _target: object;
/** @internal */ readonly _property: string;
/** @internal */ readonly _keyframes: Array<{
time: number;
value: any;
interpolation?: AnimationInterpolation;
}>;
/** @internal */ readonly _root?: Object3D;
};
/** Options for a single track */
export type TrackOptions = {
/**
* Root object for resolving the track path.
* - If `root === target` → self-targeting (`.property`)
* - If `root !== target` → named targeting (`"targetName.property"` using `target.name`)
* - If omitted → self-targeting by default
*/
root?: Object3D;
};
/** Options for {@link createAnimation} */
export type CreateAnimationOptions = {
/** Default root for all tracks that don't specify their own */
root?: Object3D;
/** Clip name (auto-generated if omitted) */
name?: string;
};
/** Create an animation track for an Object3D's position or scale */
export declare function track(target: Object3D, property: "position" | "scale", keyframes: KF<Vec3Value>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for an Object3D's quaternion */
export declare function track(target: Object3D, property: "quaternion", keyframes: KF<QuatValue>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for an Object3D's rotation (Euler angles, converted to quaternion internally) */
export declare function track(target: Object3D, property: "rotation", keyframes: KF<EulerValue>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for an Object3D's visibility */
export declare function track(target: Object3D, property: "visible", keyframes: KF<boolean>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for a material's numeric property */
export declare function track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF<number>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for a material's color property */
export declare function track(target: Material, property: "color" | "emissive", keyframes: KF<ColorValue>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for a light's numeric property */
export declare function track(target: Light, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF<number>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for a light's color */
export declare function track(target: Light, property: "color", keyframes: KF<ColorValue>, options?: TrackOptions): TrackDescriptor;
/** Create an animation track for a camera's numeric property */
export declare function track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF<number>, options?: TrackOptions): TrackDescriptor;
/**
* A fluent builder for creating `AnimationClip` instances from code.
*
* Use {@link AnimationBuilder.create} to start a new builder, chain `.track()` calls
* to add animation tracks, and call `.build()` to produce the clip.
*
* @example Single track
* ```ts
* const clip = AnimationBuilder.create()
* .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 })
* .build();
* ```
*
* @example Multiple tracks
* ```ts
* const clip = AnimationBuilder.create("DoorOpen")
* .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 })
* .track(light, "intensity", { from: 0, to: 5, duration: 1 })
* .build(room);
* ```
*
* @category Animation and Sequencing
* @group Utilities
*/
export declare class AnimationBuilder {
private _name?;
private _tracks;
/** Creates a new AnimationBuilder instance */
static create(name?: string): AnimationBuilder;
constructor(name?: string);
/** Adds an animation track for an Object3D's position or scale */
track(target: Object3D, property: "position" | "scale", keyframes: KF<Vec3Value>, options?: TrackOptions): this;
/** Adds an animation track for an Object3D's quaternion */
track(target: Object3D, property: "quaternion", keyframes: KF<QuatValue>, options?: TrackOptions): this;
/** Adds an animation track for an Object3D's rotation (Euler, converted to quaternion) */
track(target: Object3D, property: "rotation", keyframes: KF<EulerValue>, options?: TrackOptions): this;
/** Adds an animation track for an Object3D's visibility */
track(target: Object3D, property: "visible", keyframes: KF<boolean>, options?: TrackOptions): this;
/** Adds an animation track for a material's numeric property */
track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF<number>, options?: TrackOptions): this;
/** Adds an animation track for a material's color property */
track(target: Material, property: "color" | "emissive", keyframes: KF<ColorValue>, options?: TrackOptions): this;
/** Adds an animation track for a light's numeric property */
track(target: Light, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF<number>, options?: TrackOptions): this;
/** Adds an animation track for a light's color */
track(target: Light, property: "color", keyframes: KF<ColorValue>, options?: TrackOptions): this;
/** Adds an animation track for a camera's numeric property */
track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF<number>, options?: TrackOptions): this;
/**
* Builds and returns the `AnimationClip`.
* @param root - Optional root Object3D for resolving track paths.
* When provided, tracks targeting a different object use `target.name` for named resolution.
*/
build(root?: Object3D): AnimationClip;
}
/** @internal @deprecated Use {@link AnimationBuilder.create} instead */
export declare function createAnimation(options: CreateAnimationOptions, ...tracks: TrackDescriptor[]): AnimationClip;
/** @internal @deprecated Use {@link AnimationBuilder.create} instead */
export declare function createAnimation(...tracks: TrackDescriptor[]): AnimationClip;
/**
* Resolves a clip source (AnimationClip, TrackDescriptor, or TrackDescriptor[]) into an AnimationClip.
* Used internally by AnimatorControllerBuilder and TimelineBuilder.
* @internal
*/
export declare function resolveClipSource(clip: AnimationClip | TrackDescriptor | TrackDescriptor[], root?: Object3D): AnimationClip;
/** Type guard for {@link TrackDescriptor} */
export declare function isTrackDescriptor(obj: unknown): obj is TrackDescriptor;
/** Resolves an array of TrackDescriptors into an AnimationClip. @internal */
export declare function resolveToClip(descriptors: TrackDescriptor[], buildRoot?: Object3D, name?: string): AnimationClip;
export {};