diff --git a/apps/node/script.mjs b/apps/node/script.mjs index c7f8aef..7d6371f 100644 --- a/apps/node/script.mjs +++ b/apps/node/script.mjs @@ -134,63 +134,197 @@ async function createExplodingPigeon() { }) .addStateMachine({ descriptor: { - id: 'pigeon_fsm', - initial: 0, // The index of the state to start at + id: "explodingPigeon", + initial: "pigeonRunning" }, states: [ { - name: "pigeon", type: "PlaybackState", - mode: "Forward", - speed: 1, - use_frame_interpolation: true, - autoplay: true, + name: "pigeonRunning", + animationId: "", loop: true, - marker: "bird" + autoplay: true, + segment: "bird", + transitions: [ + { + type: "Transition", + toState: "explosion", + guards: [ + { + type: "Event", + triggerName: "explode" + } + ] + } + ] }, { - name: "explosion", type: "PlaybackState", - mode: "Forward", + name: "explosion", + animationId: "", + loop: false, autoplay: true, - speed: 0.5, + segment: "explosion", + transitions: [ + { + type: "Transition", + toState: "feathersFalling", + guards: [ + { + type: "Event", + triggerName: "rainFeathers" + } + ] + } + ] + }, + { + type: "PlaybackState", + name: "feathersFalling", + animationId: "", loop: false, - marker: 'explosion', + autoplay: true, + segment: "feathers", + transitions: [ + { + type: "Transition", + toState: "pigeonRunning", + guards: [ + { + type: "Event", + triggerName: "restart" + } + ] + } + ] + } + ], + listeners: [ + { + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "explode" + } + ] }, { - name: "feathers", + type: "OnComplete", + stateName: "explosion", + actions: [ + { + type: "Fire", + triggerName: "rainFeathers" + } + ] + }, + { + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "restart" + } + ] + } + ], + triggers: [ + { + type: "Event", + name: "explode" + }, + { + type: "Event", + name: "rainFeathers" + }, + { + type: "Event", + name: "restart" + } + ] + }) + .addStateMachine({ + descriptor: { + id: "pigeonWithoutExplosion", + initial: "pigeonRunning" + }, + states: [ + { type: "PlaybackState", + name: "pigeonRunning", + animationId: "", + loop: true, autoplay: true, - speed: 1, + segment: "bird", + transitions: [ + { + type: "Transition", + toState: "feathersFalling", + guards: [ + { + type: "Event", + triggerName: "explode" + } + ] + } + ] + }, + { + type: "PlaybackState", + name: "feathersFalling", + animationId: "", loop: false, - marker: 'feathers', + autoplay: true, + segment: "feathers", + transitions: [ + { + type: "Transition", + toState: "pigeonRunning", + guards: [ + { + type: "Event", + triggerName: "restart" + } + ] + } + ] } ], - transitions: [ + listeners: [ { - type: "Transition", - from_state: 0, - to_state: 1, - string_event: { - value: "explosion" - }, - // on_pointer_down_event: {}, + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "explode" + } + ] }, { - type: "Transition", - from_state: 1, - to_state: 2, - on_complete_event: {}, + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "restart" + } + ] + } + ], + triggers: [ + { + type: "Event", + name: "explode" }, { - type: "Transition", - from_state: 2, - to_state: 0, - on_complete_event: {}, + type: "Event", + name: "rainFeathers" }, - ], - listeners: [], - context_variables: [] + { + type: "Event", + name: "restart" + } + ] }) .build() .then((value) => { @@ -1115,7 +1249,7 @@ async function debugScenario() { // debugScenario(); -// createExplodingPigeon(); +createExplodingPigeon(); // createListenersAnimation(); // create_pigeon_fsm_eq_guard(); // create_pigeon_gt_gte_guard(); @@ -1124,9 +1258,9 @@ async function debugScenario() { /** Sun moon toggle button */ -create_toggle_button(); +// create_toggle_button(); /** Coffee drinker sync to scroll. Recreate the animation on the Interactivity homepage */ /* lottiefiles.com/interactivity */ -create_sync_animation(); +// create_sync_animation(); diff --git a/packages/dotlottie-js/src/common/dotlottie-common.ts b/packages/dotlottie-js/src/common/dotlottie-common.ts index 7e6d6a5..870d4e5 100644 --- a/packages/dotlottie-js/src/common/dotlottie-common.ts +++ b/packages/dotlottie-js/src/common/dotlottie-common.ts @@ -2,8 +2,6 @@ * Copyright 2023 Design Barn Inc. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import type { Animation as AnimationType } from '@lottie-animation-community/lottie-types'; import type { ZipOptions } from 'fflate'; @@ -613,9 +611,8 @@ export class DotLottieCommon { const stateOption = { states: stateMachine.states, descriptor: { id: stateMachine.id, initial: stateMachine.initial }, - transitions: stateMachine.transitions, listeners: stateMachine.listeners, - context_variables: stateMachine.contextVariables, + triggers: stateMachine.triggers, zipOptions: stateMachine.zipOptions, }; diff --git a/packages/dotlottie-js/src/common/dotlottie-state-machine-common.ts b/packages/dotlottie-js/src/common/dotlottie-state-machine-common.ts index 2cc65df..99fce8e 100644 --- a/packages/dotlottie-js/src/common/dotlottie-state-machine-common.ts +++ b/packages/dotlottie-js/src/common/dotlottie-state-machine-common.ts @@ -2,35 +2,24 @@ * Copyright 2023 Design Barn Inc. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import type { ZipOptions } from 'fflate'; import { safeParse, flatten } from 'valibot'; import type { - DotLottieContextVariables, DotLottieDescriptor, - DotLottieListener, DotLottieListeners, DotLottieStates, - DotLottieTransition, DotLottieTransitions, + DotLottieTriggers, } from './dotlottie-state'; -import { - ContextVariablesSchema, - DescriptorSchema, - ListenersSchemas, - StatesSchema, - TransitionsSchema, -} from './dotlottie-state'; +import { DescriptorSchema, ListenersSchema, StatesSchema, TransitionsSchema, TriggersSchema } from './dotlottie-state'; import { DotLottieError, ErrorCodes } from './utils'; export interface DotLottieStateMachineCommonOptions { - context_variables: DotLottieContextVariables; descriptor: DotLottieDescriptor; - listeners: DotLottieListeners; + listeners?: DotLottieListeners | undefined; states: DotLottieStates; - transitions: DotLottieTransitions; + triggers?: DotLottieTriggers | undefined; zipOptions?: ZipOptions; } @@ -41,16 +30,13 @@ export class DotLottieStateMachineCommon { protected _states: DotLottieStates; - protected _transitions: DotLottieTransition[]; - - protected _listeners: DotLottieListener[]; + protected _listeners: DotLottieListeners; - protected _contextVariables: DotLottieContextVariables; + protected _triggers: DotLottieTriggers; public constructor(options: DotLottieStateMachineCommonOptions) { - this._requireValidContextVariables(options.context_variables); - this._requireValidListeners(options.listeners); - this._requireValidTransitions(options.transitions); + this._requireValidTriggers(options.triggers ?? []); + this._requireValidListeners(options.listeners ?? []); this._requireValidId(options.descriptor.id); this._requireValidStates(options.states); this._requireValidDescriptor(options.descriptor); @@ -63,11 +49,9 @@ export class DotLottieStateMachineCommon { this._descriptor = options.descriptor; - this._listeners = options.listeners; + this._listeners = options.listeners ?? []; - this._transitions = options.transitions; - - this._contextVariables = options.context_variables; + this._triggers = options.triggers ?? []; } public get zipOptions(): ZipOptions { @@ -96,35 +80,27 @@ export class DotLottieStateMachineCommon { this._states = states; } - public get transitions(): DotLottieTransition[] { - return this._transitions; - } - - public set transitions(transitions: DotLottieTransition[]) { - this._transitions = transitions; - } - - public get listeners(): DotLottieListener[] { + public get listeners(): DotLottieListeners { return this._listeners; } - public set listeners(listeners: DotLottieListener[]) { + public set listeners(listeners: DotLottieListeners) { this._listeners = listeners; } - public get contextVariables(): DotLottieContextVariables { - return this._contextVariables; + public get triggers(): DotLottieTriggers { + return this._triggers; } - public set contextVariables(contextVariables: DotLottieContextVariables) { - this._contextVariables = contextVariables; + public set triggers(triggers: DotLottieTriggers) { + this._triggers = triggers; } - public get initial(): number { + public get initial(): string { return this._descriptor.initial; } - public set initial(initial: number) { + public set initial(initial: string) { this._descriptor.initial = initial; } @@ -140,8 +116,7 @@ export class DotLottieStateMachineCommon { return JSON.stringify({ descriptor: this._descriptor, states: this._states, - transitions: this._transitions, - context_variables: this._contextVariables, + triggers: this._triggers, listeners: this._listeners, }); } @@ -170,10 +145,17 @@ export class DotLottieStateMachineCommon { throw new DotLottieError(`Invalid states: ${error}`, ErrorCodes.INVALID_STATEMACHINE); } + + // loop over every transition and validate it + for (const state of states) { + if (state.transitions) { + this._requireValidTransitions(state.transitions); + } + } } - protected _requireValidContextVariables(contextVariables: DotLottieContextVariables): void { - const result = safeParse(ContextVariablesSchema, contextVariables); + protected _requireValidTriggers(triggers: DotLottieTriggers): void { + const result = safeParse(TriggersSchema, triggers); if (!result.success) { const error = `Invalid state machine declaration, ${JSON.stringify(flatten(result.issues).nested, null, 2)}`; @@ -183,7 +165,7 @@ export class DotLottieStateMachineCommon { } protected _requireValidListeners(listeners: DotLottieListeners): void { - const result = safeParse(ListenersSchemas, listeners); + const result = safeParse(ListenersSchema, listeners); if (!result.success) { const error = `Invalid state machine declaration, ${JSON.stringify(flatten(result.issues).nested, null, 2)}`; diff --git a/packages/dotlottie-js/src/common/dotlottie-state.ts b/packages/dotlottie-js/src/common/dotlottie-state.ts index 89f6430..85defe7 100644 --- a/packages/dotlottie-js/src/common/dotlottie-state.ts +++ b/packages/dotlottie-js/src/common/dotlottie-state.ts @@ -2,20 +2,33 @@ * Copyright 2023 Design Barn Inc. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import type { Output } from 'valibot'; -import { boolean, number, object, optional, string, array, union, tuple } from 'valibot'; - -const NumericStringBooleanType = union([string('Numeric'), string('String'), string('Boolean')]); +import { boolean, number, object, optional, string, array, union } from 'valibot'; -// Guard Schema -export const GuardSchema = object({ - type: NumericStringBooleanType, - context_key: string(), - condition_type: string(), - compare_to: union([string(), number(), boolean()]), +export const NumericGuardSchema = object({ + type: string('Numeric'), + triggerName: string(), + conditionType: string(), + compareTo: union([string(), number(), boolean()]), +}); +export const StringGuardSchema = object({ + type: string('String'), + triggerName: string(), + conditionType: string(), + compareTo: union([string(), number(), boolean()]), +}); +export const BooleanGuardSchema = object({ + type: string('Numeric'), + triggerName: string(), + conditionType: string(), + compareTo: union([string(), boolean()]), }); +export const EventGuardSchema = object({ + type: string('Event'), + triggerName: string(), +}); + +export const GuardSchema = union([NumericGuardSchema, StringGuardSchema, BooleanGuardSchema, EventGuardSchema]); // Event Schemas const NumericEventSchema = object({ value: number() }); @@ -29,106 +42,212 @@ const TransitionType = string('Transition'); // Transition Schema export const TransitionSchema = object({ type: TransitionType, - from_state: number(), - to_state: number(), + toState: string(), guards: optional(array(GuardSchema)), - numeric_event: optional(NumericEventSchema), - boolean_event: optional(BooleanEventSchema), - string_event: optional(StringEventSchema), - on_complete_event: optional(object({})), - on_pointer_down_event: optional(PointerEventSchema), - on_pointer_up_event: optional(PointerEventSchema), - on_pointer_enter_event: optional(PointerEventSchema), - on_pointer_exit_event: optional(PointerEventSchema), - on_pointer_move_event: optional(PointerEventSchema), }); export const TransitionsSchema = array(TransitionSchema); // Entry/Exit Action Schema -const URLActionSchema = object({ type: string(), url: string(), target: string() }); +const URLActionSchema = object({ type: string(), url: string() }); const ThemeActionSchema = object({ type: string(), themeId: string() }); -const SoundActionSchema = object({ type: string(), soundId: string() }); -const LogActionSchema = object({ type: string(), message: string() }); +const IncrementSchema = object({ + type: string(), + triggerName: string(), + value: optional(union([string(), number()])), +}); +const DecrementSchema = object({ + type: string(), + triggerName: string(), + value: optional(union([string(), number()])), +}); +const ToggleSchema = object({ + type: string(), + triggerName: string(), +}); +const SetBooleanSchema = object({ + type: string(), + triggerName: string(), + value: optional(boolean()), +}); +const SetStringSchema = object({ + type: string(), + triggerName: string(), + value: optional(string()), +}); +const SetNumericSchema = object({ + type: string(), + triggerName: string(), + value: optional(number()), +}); +const FireSchema = object({ + type: string(), + triggerName: string(), +}); +const ResetSchema = object({ + type: string(), + triggerName: string(), +}); +const SetExpressionSchema = object({ + type: string(), + layerName: string(), + propertyIndex: number(), + varName: string(), + value: number(), +}); +const SetThemeSchema = object({ + type: string(), + themeId: string(), +}); +const SetFrameSchema = object({ + type: string(), + value: union([string(), number()]), +}); +const SetProgressSchema = object({ + type: string(), + value: union([string(), number()]), +}); +const SetSlotSchema = object({ + type: string(), + value: string(), +}); +const FireCustomEventSchema = object({ + type: string(), + value: string(), +}); -const ActionSchema = union([URLActionSchema, ThemeActionSchema, SoundActionSchema, LogActionSchema]); +const ActionSchema = union([ + URLActionSchema, + ThemeActionSchema, + IncrementSchema, + DecrementSchema, + ToggleSchema, + SetBooleanSchema, + SetStringSchema, + SetNumericSchema, + FireSchema, + ResetSchema, + SetExpressionSchema, + SetThemeSchema, + SetFrameSchema, + SetProgressSchema, + SetSlotSchema, + FireCustomEventSchema, +]); const Modes = union([string('Forward'), string('Reverse'), string('Bounce'), string('ReverseBounce')]); -const StateType = union([string('PlaybackState'), string('FinalState'), string('SyncState'), string('GobalState')]); +const StateType = union([string('PlaybackState'), string('GlobalState')]); export const PlaybackStateSchema = object({ name: string(), type: StateType, - animation_id: optional(string()), + animationId: string(), loop: optional(boolean()), autoplay: optional(boolean()), mode: optional(Modes), speed: optional(number()), - marker: optional(string()), - background_color: optional(number()), - segment: optional(optional(tuple([number(), number()]))), - use_frame_interpolation: optional(boolean()), - reset_context: optional(string()), - entry_actions: optional(array(ActionSchema)), - exit_actions: optional(array(ActionSchema)), + segment: optional(string()), + backgroundColor: optional(number()), + useFrameInterpolation: optional(boolean()), + entryActions: optional(array(ActionSchema)), + exitActions: optional(array(ActionSchema)), + transitions: optional(TransitionsSchema), }); -export const SyncStateSchema = object({ +export const GlobalStateSchema = object({ name: string(), type: StateType, - animation_id: optional(string()), - frame_context_key: string(), - background_color: optional(number()), - segment: optional(optional(tuple([number(), number()]))), - reset_context: optional(string()), - entry_actions: optional(array(ActionSchema)), - exit_actions: optional(array(ActionSchema)), + entryActions: optional(array(ActionSchema)), + exitActions: optional(array(ActionSchema)), + transitions: optional(TransitionsSchema), }); -export const FinalStateSchema = object({ - name: string(), - type: StateType, - reset_context: optional(string()), - entry_actions: optional(array(ActionSchema)), - exit_actions: optional(array(ActionSchema)), +export const StateSchema = union([PlaybackStateSchema, GlobalStateSchema]); +export const StatesSchema = array(StateSchema); + +export const PointerUpSchema = object({ + type: string(), + layerName: optional(string()), + actions: array(ActionSchema), }); -export const GlobalStateSchema = object({ - name: string(), - type: StateType, - reset_context: optional(string()), - entry_actions: optional(array(ActionSchema)), - exit_actions: optional(array(ActionSchema)), +export const PointerDownSchema = object({ + type: string(), + layerName: optional(string()), + actions: array(ActionSchema), }); -export const StateSchema = union([PlaybackStateSchema, SyncStateSchema, FinalStateSchema, GlobalStateSchema]); -export const StatesSchema = array(StateSchema); +export const PointerEnterSchema = object({ + type: string(), + layerName: optional(string()), + actions: array(ActionSchema), +}); + +export const PointerMoveSchema = object({ + type: string(), + layerName: optional(string()), + actions: array(ActionSchema), +}); + +export const PointerExitSchema = object({ + type: string(), + layerName: optional(string()), + actions: array(ActionSchema), +}); -// Listener Schema -export const ListenerSchema = object({ +export const OnCompleteSchema = object({ type: string(), - target: optional(string()), - action: optional(string()), - value: optional(union([string(), boolean(), number()])), - context_key: optional(string()), + stateName: string(), + actions: array(ActionSchema), +}); + +export const ListenerSchema = union([ + PointerUpSchema, + PointerDownSchema, + PointerEnterSchema, + PointerMoveSchema, + PointerExitSchema, + OnCompleteSchema, +]); +export const ListenersSchema = array(ListenerSchema); + +export const NumericTriggerSchema = object({ + type: string('Numeric'), + name: string(), + value: number(), +}); + +export const StringTriggerSchema = object({ + type: string('String'), + name: string(), + value: string(), }); -export const ListenersSchemas = array(ListenerSchema); +export const BooleanTriggerSchema = object({ + type: string('String'), + name: string(), + value: boolean(), +}); -// Context Variable Schema -export const ContextVariableSchema = object({ - type: NumericStringBooleanType, - key: string(), - value: union([number(), string(), boolean()]), +export const EventTriggerSchema = object({ + type: string('Event'), + name: string(), }); -export const ContextVariablesSchema = array(ContextVariableSchema); +export const TriggerSchema = union([ + NumericTriggerSchema, + StringTriggerSchema, + BooleanTriggerSchema, + EventTriggerSchema, +]); + +export const TriggersSchema = array(TriggerSchema); // Descriptor Schema export const DescriptorSchema = object({ id: string(), - initial: number(), + initial: string(), }); export type DotLottieStates = Output; @@ -140,9 +259,10 @@ export type DotLottieBooleanEvent = Output; export type DotLottieStringEvent = Output; export type DotLottiePointerEvent = Output; export type DotLottieGuard = Output; -export type DotLottieContextVariables = Output; +export type DotLottieTrigger = Output; +export type DotLottieTriggers = Output; export type DotLottieListener = Output; -export type DotLottieListeners = Output; +export type DotLottieListeners = Output; export type DotLottieTransition = Output; export type DotLottieTransitions = Output; @@ -150,8 +270,7 @@ export type DotLottieTransitions = Output; export const DotLottieStateMachineSchema = object({ descriptor: DescriptorSchema, states: StatesSchema, - transitions: TransitionsSchema, - listeners: ListenersSchemas, - context_variables: ContextVariablesSchema, + listeners: optional(ListenersSchema), + triggers: optional(TriggersSchema), }); export type DotLottieStateMachine = Output; diff --git a/packages/dotlottie-js/src/tests/__fixtures__/simple/exploding-pigeons-test-file.lottie b/packages/dotlottie-js/src/tests/__fixtures__/simple/exploding_pigeon.lottie similarity index 93% rename from packages/dotlottie-js/src/tests/__fixtures__/simple/exploding-pigeons-test-file.lottie rename to packages/dotlottie-js/src/tests/__fixtures__/simple/exploding_pigeon.lottie index 10c282e..e42cf1c 100644 Binary files a/packages/dotlottie-js/src/tests/__fixtures__/simple/exploding-pigeons-test-file.lottie and b/packages/dotlottie-js/src/tests/__fixtures__/simple/exploding_pigeon.lottie differ diff --git a/packages/dotlottie-js/src/tests/__fixtures__/simple/state/pigeon-state.ts b/packages/dotlottie-js/src/tests/__fixtures__/simple/state/pigeon-state.ts index 288c967..8f90eb6 100644 --- a/packages/dotlottie-js/src/tests/__fixtures__/simple/state/pigeon-state.ts +++ b/packages/dotlottie-js/src/tests/__fixtures__/simple/state/pigeon-state.ts @@ -2,94 +2,241 @@ import { DotLottieStateMachine } from "../../../../common" export const PigeonState: DotLottieStateMachine = { descriptor: { - id: 'exploding_pigeon', - initial: 0, + id: "explodingPigeon", + initial: "pigeonRunning" }, states: [ { - name: "pigeon", - animation_id: "pigeon", type: "PlaybackState", + name: "pigeonRunning", + animationId: "", + loop: true, autoplay: true, - loop: false, - marker: "bird" + segment: "bird", + transitions: [ + { + type: "Transition", + toState: "explosion", + guards: [ + { + type: "Event", + triggerName: "explode" + } + ] + } + ] }, { - name: "explosion", - animation_id: "pigeon", type: "PlaybackState", + name: "explosion", + animationId: "", + loop: false, autoplay: true, - speed: 0.8, + segment: "explosion", + transitions: [ + { + type: "Transition", + toState: "feathersFalling", + guards: [ + { + type: "Event", + triggerName: "rainFeathers" + } + ] + } + ] + }, + { + type: "PlaybackState", + name: "feathersFalling", + animationId: "", loop: false, - marker: 'explosion', + autoplay: true, + segment: "feathers", + transitions: [ + { + type: "Transition", + toState: "pigeonRunning", + guards: [ + { + type: "Event", + triggerName: "restart" + } + ] + } + ] + } + ], + listeners: [ + { + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "explode" + } + ] + }, + { + type: "OnComplete", + stateName: "explosion", + actions: [ + { + type: "Fire", + triggerName: "rainFeathers" + } + ] }, { - name: "feathers", - animation_id: "pigeon", + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "restart" + } + ] + } + ], + triggers: [ + { + type: "Event", + name: "explode" + }, + { + type: "Event", + name: "rainFeathers" + }, + { + type: "Event", + name: "restart" + } + ] +} + + +export const PigeonWithoutExplosion: DotLottieStateMachine = +{ + descriptor: { + id: "pigeonWithoutExplosion", + initial: "pigeonRunning" + }, + states: [ + { type: "PlaybackState", + name: "pigeonRunning", + animationId: "", + loop: true, autoplay: true, - speed: 0.8, + segment: "bird", + transitions: [ + { + type: "Transition", + toState: "feathersFalling", + guards: [ + { + type: "Event", + triggerName: "explode" + } + ] + } + ] + }, + { + type: "PlaybackState", + name: "feathersFalling", + animationId: "", loop: false, - marker: 'feathers', + autoplay: true, + segment: "feathers", + transitions: [ + { + type: "Transition", + toState: "pigeonRunning", + guards: [ + { + type: "Event", + triggerName: "restart" + } + ] + } + ] } ], - transitions: [ + listeners: [ { - type: "Transition", - from_state: 0, - to_state: 1, - on_complete_event: {}, + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "explode" + } + ] }, { - type: "Transition", - from_state: 1, - to_state: 2, - on_complete_event: {}, + type: "PointerDown", + actions: [ + { + type: "Fire", + triggerName: "restart" + } + ] + } + ], + triggers: [ + { + type: "Event", + name: "explode" }, { - type: "Transition", - from_state: 2, - to_state: 0, - on_complete_event: {}, + type: "Event", + name: "rainFeathers" }, - ], - context_variables: [], - listeners: [] + { + type: "Event", + name: "restart" + } + ] } - export const SmileyWifi: DotLottieStateMachine = { descriptor: { id: 'simple_click_to_next_prev', - initial: 0, + initial: "smiley", }, states: [ { name: "smiley", type: "PlaybackState", - animation_id: 'smiley', + animationId: 'smiley', autoplay: true, loop: true, mode: "Reverse", speed: 2, + transitions: [ + { + type: "Transition", + toState: "wifi", + guards: [ + { + type: "Event", + triggerName: "click" + } + ] + } + ] }, { name: "wifi", type: "PlaybackState", - animation_id: 'wifi', + animationId: 'wifi', autoplay: true, loop: true, mode: "Forward", }, ], - transitions: [ - { - type: "Transition", - from_state: 0, - to_state: 1, - string_event: { value: 'click' }, - } - ], listeners: [], - context_variables: [] + triggers: [{ + type: "Event", + name: "click" + }] }; diff --git a/packages/dotlottie-js/src/tests/__fixtures__/simple/state/segments-state.ts b/packages/dotlottie-js/src/tests/__fixtures__/simple/state/segments-state.ts deleted file mode 100644 index b4ac45b..0000000 --- a/packages/dotlottie-js/src/tests/__fixtures__/simple/state/segments-state.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { DotLottieStateMachine } from "../../../../common"; - -export const PigeonWithoutExplosion: DotLottieStateMachine = - { - descriptor: { - id: 'pigeon_without_explosion', - initial: 0, - }, - states: [ - { - name: "pigeon", - animation_id: "pigeon", - type: "PlaybackState", - autoplay: true, - loop: false, - marker: "bird" - }, - { - name: "feathers", - animation_id: "pigeon", - type: "PlaybackState", - autoplay: true, - speed: 0.8, - loop: false, - marker: 'feathers', - } - ], - transitions: [ - { - type: "Transition", - from_state: 0, - to_state: 1, - on_complete_event: {}, - }, - { - type: "Transition", - from_state: 1, - to_state: 0, - on_complete_event: {}, - }, - ], - context_variables: [], - listeners: [] - } diff --git a/packages/dotlottie-js/src/tests/lottie-state-browser.spec.ts b/packages/dotlottie-js/src/tests/lottie-state-browser.spec.ts index 28c8f80..9d2937f 100644 --- a/packages/dotlottie-js/src/tests/lottie-state-browser.spec.ts +++ b/packages/dotlottie-js/src/tests/lottie-state-browser.spec.ts @@ -3,7 +3,6 @@ */ /* eslint-disable no-new */ -/* eslint-disable @typescript-eslint/naming-convention */ import type { AnimationData } from '../common'; import { DotLottie } from '../dotlottie'; @@ -19,11 +18,10 @@ describe('LottieState', () => { expect(() => { // act new LottieStateMachine({ - descriptor: { id: '', initial: 0 }, + descriptor: { id: '', initial: 'pigeon' }, states: PigeonState.states, - listeners: PigeonState.listeners, - transitions: PigeonState.transitions, - context_variables: PigeonState.context_variables, + listeners: PigeonState.listeners ?? [], + triggers: PigeonState.triggers ?? [], }); // assert }).toThrowError('Invalid id.'); @@ -31,11 +29,10 @@ describe('LottieState', () => { it('gets and sets the zipOptions', () => { const theme = new LottieStateMachine({ - descriptor: { id: 'test', initial: 0 }, + descriptor: PigeonState.descriptor, states: PigeonState.states, - listeners: PigeonState.listeners, - transitions: PigeonState.transitions, - context_variables: PigeonState.context_variables, + listeners: PigeonState.listeners ?? [], + triggers: PigeonState.triggers ?? [], zipOptions: { level: 9, mem: 1, @@ -59,7 +56,7 @@ describe('LottieState', () => { it('gets and sets the id', () => { // arrange const state = new LottieStateMachine({ - descriptor: { id: 'test', initial: 0 }, + descriptor: { id: 'test', initial: 'test' }, states: [ { name: 'test', @@ -68,9 +65,6 @@ describe('LottieState', () => { autoplay: true, }, ], - listeners: [], - transitions: [], - context_variables: [], }); expect(state.id).toEqual('test'); diff --git a/packages/dotlottie-js/src/tests/lottie-state-node.spec.ts b/packages/dotlottie-js/src/tests/lottie-state-node.spec.ts index ae3625e..f9d85ea 100644 --- a/packages/dotlottie-js/src/tests/lottie-state-node.spec.ts +++ b/packages/dotlottie-js/src/tests/lottie-state-node.spec.ts @@ -3,7 +3,6 @@ */ /* eslint-disable no-new */ -/* eslint-disable @typescript-eslint/naming-convention */ import type { AnimationData } from '../common'; import { DotLottie } from '../dotlottie'; @@ -19,11 +18,10 @@ describe('LottieState', () => { expect(() => { // act new LottieStateMachine({ - descriptor: { id: '', initial: 0 }, + descriptor: { id: '', initial: 'pigeon' }, states: [], - transitions: [], listeners: [], - context_variables: [], + triggers: [], }); // assert }).toThrowError('Invalid id.'); @@ -31,11 +29,10 @@ describe('LottieState', () => { it('gets and sets the zipOptions', () => { const theme = new LottieStateMachine({ - descriptor: { id: 'test', initial: 0 }, - states: [], - transitions: [], - listeners: [], - context_variables: [], + descriptor: PigeonState.descriptor, + states: PigeonState.states, + listeners: PigeonState.listeners ?? [], + triggers: PigeonState.triggers ?? [], zipOptions: { level: 9, mem: 1, @@ -59,11 +56,15 @@ describe('LottieState', () => { it('gets and sets the id', () => { // arrange const state = new LottieStateMachine({ - descriptor: { id: 'test', initial: 0 }, - states: [], - transitions: [], - listeners: [], - context_variables: [], + descriptor: { id: 'test', initial: 'test' }, + states: [ + { + name: 'test', + type: 'PlaybackState', + mode: 'Forward', + autoplay: true, + }, + ], }); expect(state.id).toEqual('test'); @@ -80,9 +81,8 @@ describe('LottieState', () => { const pigeonState = new LottieStateMachine({ descriptor: PigeonState.descriptor, states: PigeonState.states, - transitions: PigeonState.transitions, listeners: PigeonState.listeners, - context_variables: PigeonState.context_variables, + triggers: PigeonState.triggers, }); // assert diff --git a/packages/dotlottie-js/src/tests/utils-browser.spec.ts b/packages/dotlottie-js/src/tests/utils-browser.spec.ts index 3de453d..a20a024 100644 --- a/packages/dotlottie-js/src/tests/utils-browser.spec.ts +++ b/packages/dotlottie-js/src/tests/utils-browser.spec.ts @@ -35,9 +35,8 @@ import dotLottieManifest from './__fixtures__/simple/animation/manifest.json'; import dotLottieTheme from './__fixtures__/simple/animation/themes/theme1.json'; import dotLottieAnimationWithImages from './__fixtures__/simple/big-merged-dotlottie.lottie'; import bullAnimation from './__fixtures__/simple/bull.lottie'; -import stateAnimation from './__fixtures__/simple/exploding-pigeons-test-file.lottie'; -import { PigeonState } from './__fixtures__/simple/state/pigeon-state'; -import { PigeonWithoutExplosion } from './__fixtures__/simple/state/segments-state'; +import stateAnimation from './__fixtures__/simple/exploding_pigeon.lottie'; +import { PigeonState, PigeonWithoutExplosion } from './__fixtures__/simple/state/pigeon-state'; describe('createError', () => { it('returns an instance of Error with the correct message', () => { @@ -252,9 +251,9 @@ describe('getStateMachine', () => { }); it('gets state machine by id', async () => { - const stateMachine = await getStateMachine(stateAnimation, 'pigeon_without_explosion'); + const stateMachine = await getStateMachine(stateAnimation, 'explodingPigeon'); - expect(stateMachine?.states).toEqual(PigeonWithoutExplosion.states); + expect(stateMachine?.states).toEqual(PigeonState.states); }); }); @@ -332,8 +331,8 @@ describe('getStateMachines', () => { it('returns a map of state machines', async () => { const stateMachines = await getStateMachines(stateAnimation); - expect(stateMachines['pigeon_without_explosion']).toEqual(JSON.stringify(PigeonWithoutExplosion)); - expect(stateMachines['exploding_pigeon']).toEqual(JSON.stringify(PigeonState)); + expect(JSON.parse(stateMachines['pigeonWithoutExplosion'] ?? '')).toEqual(PigeonWithoutExplosion); + expect(JSON.parse(stateMachines['explodingPigeon'] ?? '')).toEqual(PigeonState); }); it('returns a map of themes with filter', async () => { diff --git a/packages/dotlottie-js/src/tests/utils-node.spec.ts b/packages/dotlottie-js/src/tests/utils-node.spec.ts index 5463c11..014d111 100644 --- a/packages/dotlottie-js/src/tests/utils-node.spec.ts +++ b/packages/dotlottie-js/src/tests/utils-node.spec.ts @@ -35,9 +35,8 @@ import dotLottieManifest from './__fixtures__/simple/animation/manifest.json'; import dotLottieTheme from './__fixtures__/simple/animation/themes/theme1.json'; import dotLottieAnimationWithImages from './__fixtures__/simple/big-merged-dotlottie.lottie'; import bullAnimation from './__fixtures__/simple/bull.lottie'; -import stateAnimation from './__fixtures__/simple/exploding-pigeons-test-file.lottie'; -import { PigeonState } from './__fixtures__/simple/state/pigeon-state'; -import { PigeonWithoutExplosion } from './__fixtures__/simple/state/segments-state'; +import stateAnimation from './__fixtures__/simple/exploding_pigeon.lottie'; +import { PigeonState, PigeonWithoutExplosion } from './__fixtures__/simple/state/pigeon-state'; describe('createError', () => { it('returns an instance of Error with the correct message', () => { @@ -260,7 +259,7 @@ describe('getStateMachine', () => { }); it('gets state machine by id', async () => { - const stateMachine = await getStateMachine(stateAnimation, 'pigeon_without_explosion'); + const stateMachine = await getStateMachine(stateAnimation, 'pigeonWithoutExplosion'); expect(stateMachine?.states).toEqual(PigeonWithoutExplosion.states); }); @@ -296,8 +295,8 @@ describe('getStateMachines', () => { it('returns a map of state machines', async () => { const stateMachines = await getStateMachines(stateAnimation); - expect(stateMachines['pigeon_without_explosion']).toEqual(JSON.stringify(PigeonWithoutExplosion)); - expect(stateMachines['exploding_pigeon']).toEqual(JSON.stringify(PigeonState)); + expect(JSON.parse(stateMachines['pigeonWithoutExplosion'] ?? '')).toEqual(PigeonWithoutExplosion); + expect(JSON.parse(stateMachines['explodingPigeon'] ?? '')).toEqual(PigeonState); }); it('returns a map of themes with filter', async () => {