Animation

Clips support three types of animations by default: In, Loop, and Out. These animations are compatible with each other but serve distinct purposes:

  • In: The animation that plays when the clip starts.
  • Out: The animation that plays when the clip reaches its end.
  • Loop: The animation that plays between the In and Out animations, cycling based on the loop count.

Animation Implementation

Animations are implemented using keyframes with ease-in/out presets. These presets utilize property identifiers as targets to define the animation behavior.

Animation Data Structure

The AnimationData interface defines the structure for creating animations. This interface includes several properties that control the behavior of the animation:

interface AnimationData {
  name: string; // Identifier used for display/debugging [default: ""]
  speed?: number; // Playback speed, 2 = faster, 0.5 = slower [default: 1]
  offset?: number; // Offset in seconds for the animation keyframes [default: 0]
  amplification?: number; // Amplifies the effect for relative properties [default: 0]
  inOutOfRange?: OutOfRangeEnum; // Handle values out of range: original or first keyframe? [default: NONE (use original)]
  outOutOfRange?: OutOfRangeEnum; // Handle values out of range: original or last keyframe? [default: NONE (use original)]
  propertyAnimations: PropertyAnimation[]; // List of individual property animations
}

Property Animation

Each property of a clip can have its own animation, defined by the PropertyAnimation interface. This interface includes a list of keyframes that specify the animation's timing and behavior:

interface PropertyAnimation {
  property: string; // Identifier for a specific property (e.g., PositionX, ScaleX, etc.)
  inOutOfRange?: OutOfRangeEnum; // Handle values out of range: original or first keyframe? [default: NONE (use original)]
  outOutOfRange?: OutOfRangeEnum; // Handle values out of range: original or last keyframe? [default: NONE (use original)]
  keyframes: Keyframe[]; // List of keyframes, with easing determined by the previous keyframe
}

Keyframes

Keyframes are the building blocks of animations, defining specific values at certain times within the animation timeline. They can handle both numeric and string values and are applied in various visual spaces such as absolute or relative:

interface Keyframe {
  time: number; // Time in seconds, offset by AnimationData.offset if set
  value: number | string; // Value at that time; numeric values are interpolated, strings are set as-is (e.g., text properties)
  easing?: EasingEnum; // Easing preset for the time segment defined by this and the next keyframe [default: linearInOut]
  space?: AnimationSpaceEnum; // Space to use for the keyframe [default: AnimationSpaceEnum.ABSOLUTE]
  relativeProperty?: string; // Base value property for relative animations [default: self/property name]
}

Keyframe Value Application

  • Relative Properties: You can specify a base property using the relativeProperty field, which defaults to the same property if not set.
  • Value Behavior: Keyframe values apply to the same base value and do not stack up.

Clip Animation Mechanics

Clips and their descendants utilize specific methods to manage animation properties. These methods include:

  • setAnimationPropertyValue: Sets the absolute value of a particular property. Clips decide whether to use offsets or store absolute values.
  • getAnimationPropertyValue: Retrieves the current, raw, non-affected property value, which the animation controller uses to apply animations correctly.
  • resetAnimationPropertyValue: Resets a specific property to its original value.
  • resetAllAnimationProperties: Resets all properties by calling resetAnimationPropertyValue for each supported property.

Example: Animation Data Object

Here’s an example of an AnimationData object that defines animations for position and scale properties:

const animationData: AnimationData = {
  name: "Test",
  outOutOfRange: OutOfRangeEnum.LOOP,
  propertyAnimations: [
    {
      property: "positionX",
      inOutOfRange: OutOfRangeEnum.EXTEND,
      outOutOfRange: OutOfRangeEnum.EXTEND,
      keyframes: [
        {
          time: 0,
          value: -3000,
          easing: EasingEnum.ElasticOut,
          space: AnimationSpaceEnum.RELATIVE_ADDITIVE,
        },
        { time: 0.75, value: 0, space: AnimationSpaceEnum.RELATIVE_ADDITIVE },
      ],
    },
    {
      property: "scaleX",
      inOutOfRange: OutOfRangeEnum.EXTEND,
      outOutOfRange: OutOfRangeEnum.EXTEND,
      keyframes: [
        {
          time: 0,
          value: 0.5,
          easing: EasingEnum.LinearIn,
          space: AnimationSpaceEnum.ABSOLUTE,
        },
        {
          time: 1,
          value: 0.5,
          easing: EasingEnum.ElasticInOut,
          space: AnimationSpaceEnum.ABSOLUTE,
        },
        { time: 2, value: 2, space: AnimationSpaceEnum.ABSOLUTE },
      ],
    },
    {
      property: "scaleY",
      inOutOfRange: OutOfRangeEnum.EXTEND,
      outOutOfRange: OutOfRangeEnum.EXTEND,
      keyframes: [
        {
          time: 0,
          value: 0.5,
          easing: EasingEnum.LinearIn,
          space: AnimationSpaceEnum.ABSOLUTE,
        },
        {
          time: 1,
          value: 0.5,
          easing: EasingEnum.ElasticInOut,
          space: AnimationSpaceEnum.ABSOLUTE,
        },
        { time: 2, value: 2, space: AnimationSpaceEnum.ABSOLUTE },
      ],
    },
  ],
};

Animation Control Methods

To manipulate clip animations, use the following methods:

clip.animationController.setAnimation(type: AnimationTypeEnum, data: AnimationData);
clip.animationController.loadAnimation(type: AnimationTypeEnum, data: string);
clip.animationController.setAnimationDuration(type: AnimationTypeEnum, durationInSeconds: number);
clip.animationController.removeAnimation(type: AnimationTypeEnum);
clip.animationController.setLoopCount(count: number);

Prioritization and Looping

The controller prioritizes the In, Out, and Loop points in that order. If all three cannot fit within the clip’s timeline, the In animation is prioritized first, followed by Out, and then Loop.

  • Loop Time: Automatically determined based on the durations of the In and Out animations and is stretched to cover the entire clip timeline (from StartBounds to EndBounds).
  • Loop Count: Set the number of times the Loop animation should repeat between the In and Out animations using the setLoopCount method.

For a comprehensive list of all supported properties and methods, be sure to check out the API Reference.