Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(animation): refactor Animation class to a separate module #356

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions js/src/animation/Animation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import type {
LinearAnimationInstance,
LinearAnimation,
Artboard,
RiveCanvas,
} from "./../rive_advanced.mjs";

/**
* Represents an animation that can be played on an Artboard.
* Wraps animations and instances from the runtime and keeps track of playback state.
*
* The `Animation` class manages the state and behavior of a single animation instance,
* including its current time, loop count, and ability to scrub to a specific time.
*
* The class provides methods to advance the animation, apply its interpolated keyframe
* values to the Artboard, and clean up the underlying animation instance when the
* animation is no longer needed.
*/
export class Animation {
public loopCount = 0;
public readonly instance: LinearAnimationInstance;

/**
* The time to which the animation should move to on the next render.
* If not null, the animation will scrub to this time instead of advancing by the given time.
*/
public scrubTo: number | null = null;

/**
* Constructs a new animation
* @constructor
* @param {any} animation: runtime animation object
* @param {any} instance: runtime animation instance object
*/
constructor(
private animation: LinearAnimation,
private artboard: Artboard,
runtime: RiveCanvas,
public playing: boolean
) {
this.instance = new runtime.LinearAnimationInstance(animation, artboard);
}

/**
* Returns the animation's name
*/
public get name(): string {
return this.animation.name;
}

/**
* Returns the animation's name
*/
public get time(): number {
return this.instance.time;
}

/**
* Sets the animation's current time
*/
public set time(value: number) {
this.instance.time = value;
}

/**
* Returns the animation's loop type
*/
public get loopValue(): number {
return this.animation.loopValue;
}

/**
* Indicates whether the animation needs to be scrubbed.
* @returns `true` if the animation needs to be scrubbed, `false` otherwise.
*/
public get needsScrub(): boolean {
return this.scrubTo !== null;
}

/**
* Advances the animation by the give time. If the animation needs scrubbing,
* time is ignored and the stored scrub value is used.
* @param time the time to advance the animation by if no scrubbing required
*/
public advance(time: number) {
if (this.scrubTo === null) {
this.instance.advance(time);
} else {
this.instance.time = 0;
this.instance.advance(this.scrubTo);
this.scrubTo = null;
}
}

/**
* Apply interpolated keyframe values to the artboard. This should be called after calling
* .advance() on an animation instance so that new values are applied to properties.
*
* Note: This does not advance the artboard, which updates all objects on the artboard
* @param mix - Mix value for the animation from 0 to 1
*/
public apply(mix: number) {
this.instance.apply(mix);
}

/**
* Deletes the backing Wasm animation instance; once this is called, this
* animation is no more.
*/
public cleanup() {
this.instance.delete();
}
}
1 change: 1 addition & 0 deletions js/src/animation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Animation } from "./Animation";
87 changes: 1 addition & 86 deletions js/src/rive.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as rc from "./rive_advanced.mjs";
import * as packageData from "package.json";
import { Animation } from './animation';
import { registerTouchInteractions, sanitizeUrl, BLANK_URL } from "./utils";

// Note: Re-exporting a few types from rive_advanced.mjs to expose for high-level
Expand Down Expand Up @@ -259,92 +260,6 @@ export class RuntimeLoader {

// #endregion

// #region animations

// Wraps animations and instances from the runtime and keeps track of playback
// state
class Animation {
public loopCount = 0;
public readonly instance: rc.LinearAnimationInstance;

// Time to which the animation should move to on the next render
public scrubTo: number | null = null;

/**
* Constructs a new animation
* @constructor
* @param {any} animation: runtime animation object
* @param {any} instance: runtime animation instance object
*/
constructor(
private animation: rc.LinearAnimation,
private artboard: rc.Artboard,
runtime: rc.RiveCanvas,
public playing: boolean,
) {
this.instance = new runtime.LinearAnimationInstance(animation, artboard);
}

// Returns the animation's name
public get name(): string {
return this.animation.name;
}

// Returns the animation's current time
public get time(): number {
return this.instance.time;
}

// Sets the animation's current time
public set time(value: number) {
this.instance.time = value;
}

// Returns the animation's loop type
public get loopValue(): number {
return this.animation.loopValue;
}

/**
* Advances the animation by the give time. If the animation needs scrubbing,
* time is ignored and the stored scrub value is used.
* @param time the time to advance the animation by if no scrubbing required
*/
public advance(time: number) {
if (this.scrubTo === null) {
this.instance.advance(time);
} else {
this.instance.time = 0;
this.instance.advance(this.scrubTo);
this.scrubTo = null;
}
}

/**
* Apply interpolated keyframe values to the artboard. This should be called after calling
* .advance() on an animation instance so that new values are applied to properties.
*
* Note: This does not advance the artboard, which updates all objects on the artboard
* @param mix - Mix value for the animation from 0 to 1
*/
public apply(mix: number) {
this.instance.apply(mix);
}

public get needsScrub(): boolean {
return this.scrubTo !== null;
}

/**
* Deletes the backing Wasm animation instance; once this is called, this
* animation is no more.
*/
public cleanup() {
this.instance.delete();
}
}

// #endregion

// #region state machines

Expand Down