import * as _esotericsoftware_spine_core from '@esotericsoftware/spine-core'; import { ContainerOptions, CanvasBaseItemMemory, ListenerExtensionMemory, AdditionalPositionsExtensionProps, AnchorExtensionProps, CanvasBaseItem, AnchorExtension, ListenerExtension, AdditionalPositionsExtension, OnEventsHandlers } from '@drincs/pixi-vn'; import { SpineFromOptions, TrackEntry, SpineOptions as SpineOptions$1, Spine as Spine$1 } from '@drincs/pixi-vn-spine/core'; import { AnimationOptionsCommon } from '@drincs/pixi-vn/motion'; import { SequenceOptions, AnimationPlaybackControlsWithThen } from 'motion'; import { ContainerEvents, ContainerChild, EventEmitter, PointData, ObservablePoint } from 'pixi.js'; interface SpineOptions extends Omit, Omit { /** * The name of the skin to set on the skeleton as soon as it is created, equivalent to calling * {@link Spine.setSkin} right after construction. */ skin?: string; /** * The name of the animation to play in loop * on track 0 as soon as the skeleton is created, equivalent * to calling {@link Spine.addAnimation} right after construction. */ animation?: string; } type SpineSequenceOptions = Pick & { /** * Whether the animation should loop. If true, the animation will loop indefinitely until changed. */ loop?: boolean; /** * Delay in seconds before the animation starts. If not provided, the animation will start immediately after the previous animation on the track, or after the mix duration if there is a previous animation. * If > 0, sets TrackEntry#delay. If <= 0, the delay set is the duration of the previous track entry * minus any mix duration (from the AnimationStateData) plus the specified `delay` (ie the mix * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the * previous entry is looping, its next loop completion is used instead of its duration. */ delay?: number; }; interface TrackMemory extends Omit, "animation"> { animationName: string; } interface MemoryCore extends Omit { } interface SpineMemory extends MemoryCore, CanvasBaseItemMemory, ListenerExtensionMemory, AdditionalPositionsExtensionProps, AnchorExtensionProps, Omit { state: { tracks: (TrackMemory | null)[]; }; currentSkin?: string; sequenceTimelines: { [track: number]: { sequence: ([string, SpineSequenceOptions] | string)[]; options: SequenceOptions & { completeOnContinue?: boolean; }; }; }; } /** * Spine component for Pixi.js, used to display Spine components. * @example * ```ts * import { Assets, canvas } from "@drincs/pixi-vn"; * import { Spine } from "@drincs/pixi-vn-spine"; * * await Assets.load([ * { * alias: "spineSkeleton", * src: "https://raw.githubusercontent.com/pixijs/spine-v8/main/examples/assets/spineboy-pro.skel", * }, * { * alias: "spineAtlas", * src: "https://raw.githubusercontent.com/pixijs/spine-v8/main/examples/assets/spineboy-pma.atlas", * }, * ]); * * const spine = new Spine({ atlas: "spineAtlas", skeleton: "spineSkeleton" }); * spine.x = canvas.width / 2; * spine.y = canvas.height; * * canvas.add("spine", spine); * ``` */ declare class Spine extends Spine$1 implements CanvasBaseItem, AnchorExtension, ListenerExtension, AdditionalPositionsExtension { /** * @param options Options used to configure the Spine skeleton (skeleton/atlas aliases, scale, dark tint, auto update, initial skin, initial animation) * plus the standard {@link CanvasBaseItem} container options (anchor, align, percentagePosition, etc.). */ constructor(options: SpineOptions); readonly pixivnId: string; /** The asset alias of the skeleton this component was created with. */ readonly skeletonAlias: SpineOptions["skeleton"]; /** The asset alias of the atlas this component was created with. */ readonly atlasAlias: SpineOptions["atlas"]; /** * Whether the dark tint renderer is used for this skeleton. If `true`, uses the dark tint renderer; if * `false`, uses the default pixi renderer; if `undefined`, the dark tint renderer is used only when at * least one slot has tint black. */ readonly darkTintCore: SpineOptions["darkTint"]; /** * Tracks the running {@link playSequence} timelines, keyed by track index, so they can be * inspected, stopped ({@link clearTrack}, {@link clearTracks}) or serialized ({@link memory}). */ private sequenceTimelines; get memory(): SpineMemory; setMemory(memory: SpineMemory): Promise; /** * Sets the current animation on a track, replacing whatever is currently playing on it. Use * {@link addAnimation} instead to queue an animation after the current one. * @param animationName The name of the animation to set. * @param options Additional options for setting the animation. * @returns The `TrackEntry` for the animation, or `null` if the animation could not be found. */ setAnimation(animationName: string, options: { /** * The track index to play the animation on. */ trackIndex: number; /** * Whether the animation should loop. If true, the animation will loop indefinitely until changed. */ loop?: boolean; /** * If true, the animation will be completed before the next step. * @default true */ completeOnContinue?: boolean; }): _esotericsoftware_spine_core.TrackEntry; /** * Queues an animation to play on a track after the current animation (if any) completes. Use * {@link setAnimation} instead to replace the track's current animation immediately. * @param animationName The name of the animation to queue. * @param options Additional options for playing the track. * @returns The `TrackEntry` for the queued animation, or `null` if the animation could not be found. */ addAnimation(animationName: string, options?: { /** * Whether the animation should loop. If true, the animation will loop indefinitely until changed. */ loop?: boolean; /** * Delay in seconds before the animation starts. If not provided, the animation will start immediately after the previous animation on the track, or after the mix duration if there is a previous animation. * If > 0, sets TrackEntry#delay. If <= 0, the delay set is the duration of the previous track entry * minus any mix duration (from the AnimationStateData) plus the specified `delay` (ie the mix * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the * previous entry is looping, its next loop completion is used instead of its duration. */ delay?: number; /** * The track index to play the animation on. */ trackIndex?: number; /** * If true, the animation will be completed before the next step. * @default true */ completeOnContinue?: boolean; }): _esotericsoftware_spine_core.TrackEntry; /** * Plays a sequence of animations on a track, one after another, driven by a `motion` timeline. Any * animation currently playing on the track is cleared first. The sequence is tracked in * {@link sequenceTimelines} (and thus included in {@link memory}) until it completes, at which point * the track is cleared automatically. * @param sequence The sequence of animations to play, with their respective options. Corresponds to the motion sequence settings: https://motion.dev/docs/animate#timeline-sequences * @param options Additional options for playing the track. * @returns The `motion` timeline controls for the sequence (without `pause`, since pausing is not supported). * @example * ```ts * spine.playSequence([ * ["walk", { loop: true, duration: 2 }], * ["jump", { delay: 0.5 }], * ], { loop: true, completeOnContinue: true }); * ``` */ playSequence(sequence: ([string, SpineSequenceOptions] | string)[], options?: SequenceOptions & { /** * If true, the animation will be completed before the next step. * @default true */ completeOnContinue?: boolean; /** * The track index to play the animation on. */ trackIndex?: number; }): Omit; /** * Builds and starts the `motion` timeline backing {@link playSequence}: each sequence entry becomes a * timeline segment whose `onPlay` calls {@link addAnimation} for the corresponding animation, using * the animation's own duration when no explicit `duration` is given. Entries whose animation is not * found on the skeleton are skipped (with a warning). */ private setTrackSequence; /** * Removes all animations from all tracks, stopping any running {@link playSequence} timelines, and * leaving the skeleton in its current pose. */ clearTracks(): void; /** * Removes all animations from a single track, stopping its running {@link playSequence} timeline (if * any), and leaving the skeleton in its current pose. * @param trackIndex The track index to clear. */ clearTrack(trackIndex: number): void; /** * Sets the active skin on the skeleton and refreshes its pose slots accordingly. Failures (e.g. an * unknown skin name) are logged via {@link logger.error} rather than thrown. * @param skinName The name of the skin to set. */ setSkin(skinName: string): void; /** ListenerExtension */ /** * The registered event handlers for this component, used by {@link setMemory}/{@link memory} to * persist and restore listeners added via {@link on}. */ readonly onEventsHandlers: OnEventsHandlers; on | keyof { [K: symbol]: any; [K: {} & string]: any; }>(event: T, fn: (...args: [ ...EventEmitter.ArgumentMap & { [K: symbol]: any; [K: {} & string]: any; }>[Extract | keyof { [K: symbol]: any; [K: {} & string]: any; }>], typeof this ]) => void, context?: any): this; /** Anchor */ private _anchor?; get anchor(): PointData; set anchor(value: PointData | number); protected reloadAnchor(): void; get pivot(): ObservablePoint; set pivot(value: ObservablePoint); /** AdditionalPositions */ private _align; set align(value: Partial | number); get align(): Partial | number; set xAlign(value: number); get xAlign(): number; set yAlign(value: number); get yAlign(): number; private _percentagePosition; set percentagePosition(value: Partial | number); get percentagePosition(): Partial | number; set percentageX(_value: number); get percentageX(): number; set percentageY(_value: number); get percentageY(): number; get positionType(): "pixel" | "percentage" | "align"; get positionInfo(): { x: number; y: number; type: "pixel" | "percentage" | "align"; }; set positionInfo(value: { x: number; y: number; type?: "pixel" | "percentage" | "align"; }); /** * Re-applies whichever positioning mode is active ({@link align} or {@link percentagePosition}) onto * the underlying pixel {@link x}/{@link y}, e.g. after the skeleton's size, scale or angle changes. * No-op when neither mode is set (plain pixel positioning). */ protected reloadPosition(): void; get position(): ObservablePoint; set position(value: ObservablePoint); get x(): number; set x(value: number); get y(): number; set y(value: number); } export { Spine, type SpineMemory, type SpineOptions, type SpineSequenceOptions, type TrackMemory };