mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
[ts][pixi-v7][pixi-v8] Add static createOptions for Spine init config to simplify subclassing; deprecate from(). (#2950)
* [ts][pixi-v7] extract Spine initialization data into getSpineInitData method * [ts][pixi-v8] extract Spine initialization data into getSpineInitData method * [ts][pixi-v8] Renamed getSpineInitData to createOptions. Deprecated from in favor of constructor accepting both SpineOptions and SpineFromOptions. * [ts][pixi-v7] Renamed getSpineInitData to createOptions. Deprecated from in favor of constructor accepting both SpineOptions and SpineFromOptions. * [ts][pixi-v7][pixi-v8] Refactored constructor. --------- Co-authored-by: Eugene Avtukhov <eugene.avtukhov@3oaks.com> Co-authored-by: Davide Tantillo <iamdjj@gmail.com>
This commit is contained in:
parent
4a5cf750f5
commit
5bfb51ed0b
@ -29,21 +29,21 @@
|
||||
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy1 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2 });
|
||||
const spineboy1 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2 });
|
||||
|
||||
const spineboy2 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy2 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.SetupPoseBoundsProvider(),
|
||||
});
|
||||
|
||||
const spineboy3 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy3 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.SkinsAndAnimationBoundsProvider("portal", undefined, undefined, false),
|
||||
});
|
||||
|
||||
const spineboy4 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy4 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.SkinsAndAnimationBoundsProvider("portal", undefined, undefined, true),
|
||||
});
|
||||
|
||||
const spineboy5 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy5 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.AABBRectangleBoundsProvider(-100, -100, 100, 100),
|
||||
});
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@
|
||||
bounds;
|
||||
|
||||
constructor(bounds) {
|
||||
const spineboy = spine.Spine.from({
|
||||
const spineboy = new spine.Spine({
|
||||
atlas: "spineboyAtlas",
|
||||
skeleton: "spineboyData",
|
||||
scale: 0.125,
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
await PIXI.Assets.load(["stretchymanData", "stretchymanAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const stretchyman = spine.Spine.from({skeleton: "stretchymanData", atlas: "stretchymanAtlas",
|
||||
const stretchyman = new spine.Spine({skeleton: "stretchymanData", atlas: "stretchymanAtlas",
|
||||
scale: 0.75,
|
||||
});
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the Spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
await PIXI.Assets.load(["skelBase64", "atlasBase64"]);
|
||||
|
||||
// creating spine game object with base64 data
|
||||
const base64GameObject = spine.Spine.from({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
const base64GameObject = new spine.Spine({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
app.stage.addChild(base64GameObject);
|
||||
base64GameObject.state.setAnimation(0, "animation", true);
|
||||
base64GameObject.position.set(window.innerWidth / 3, window.innerHeight / 2);
|
||||
@ -91,7 +91,7 @@
|
||||
await PIXI.Assets.load(["skelBlob", "atlasBlob"]);
|
||||
|
||||
// creating spine game object
|
||||
const blobGameObject = spine.Spine.from({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
const blobGameObject = new spine.Spine({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
app.stage.addChild(blobGameObject);
|
||||
blobGameObject.state.setAnimation(0, "animation", true);
|
||||
blobGameObject.position.set(window.innerWidth / 3 * 2, window.innerHeight / 2);
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["mixAndMatchData", "mixAndMatchAtlas"]);
|
||||
|
||||
// Create the Spine display object
|
||||
const mixAndMatch = spine.Spine.from({skeleton: "mixAndMatchData", atlas: "mixAndMatchAtlas",
|
||||
const mixAndMatch = new spine.Spine({skeleton: "mixAndMatchData", atlas: "mixAndMatchAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const sack = spine.Spine.from({skeleton: "sackData", atlas: "sackAtlas",
|
||||
const sack = new spine.Spine({skeleton: "sackData", atlas: "sackAtlas",
|
||||
scale: 0.2,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["girlData", "girlAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const girl = spine.Spine.from({skeleton: "girlData", atlas: "girlAtlas",
|
||||
const girl = new spine.Spine({skeleton: "girlData", atlas: "girlAtlas",
|
||||
scale: 0.2,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["snowglobeData", "snowglobeAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const snowglobe = spine.Spine.from({skeleton: "snowglobeData", atlas: "snowglobeAtlas",
|
||||
const snowglobe = new spine.Spine({skeleton: "snowglobeData", atlas: "snowglobeAtlas",
|
||||
scale: 0.25,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["cloudPotData", "cloudPotAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const cloudPot = spine.Spine.from({skeleton: "cloudPotData", atlas: "cloudPotAtlas",
|
||||
const cloudPot = new spine.Spine({skeleton: "cloudPotData", atlas: "cloudPotAtlas",
|
||||
scale: 0.25,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
PIXI.Assets.cache.set("spineboyAtlas", textureAtlas);
|
||||
|
||||
// creating spine game object
|
||||
const spineGO = spine.Spine.from({skeleton: "jsonSkel", atlas: "spineboyAtlas" });
|
||||
const spineGO = new spine.Spine({skeleton: "jsonSkel", atlas: "spineboyAtlas" });
|
||||
spineGO.position.set(300, 300);
|
||||
app.stage.addChild(spineGO);
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.25,
|
||||
});
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Application, Assets } from 'pixi.js';
|
||||
import { Spine } from '@esotericsoftware/spine-pixi-v7';
|
||||
import { Application, Assets } from 'pixi.js';
|
||||
|
||||
/** The PixiJS app Application instance, shared across the project */
|
||||
export const app = new Application<HTMLCanvasElement>({
|
||||
@ -23,7 +23,8 @@ async function init () {
|
||||
await Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = Spine.from("spineboyData", "spineboyAtlas", {
|
||||
const spineboy = new Spine({
|
||||
skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ import {
|
||||
Skeleton,
|
||||
SkeletonBinary,
|
||||
SkeletonClipping,
|
||||
SkeletonData,
|
||||
type SkeletonData,
|
||||
SkeletonJson,
|
||||
Skin,
|
||||
Utils,
|
||||
@ -247,7 +247,8 @@ export class SkinsAndAnimationBoundsProvider
|
||||
|
||||
/**
|
||||
* The class to instantiate a {@link Spine} game object in Pixi.
|
||||
* The static method {@link Spine.from} should be used to instantiate a Spine game object.
|
||||
* Create and customize the default configuration using the static method {@link Spine.createOptions},
|
||||
* then pass it to the constructor.
|
||||
*/
|
||||
export class Spine extends Container {
|
||||
/** The skeleton for this Spine game object. */
|
||||
@ -328,29 +329,23 @@ export class Spine extends Container {
|
||||
private _boundsSpineID = -1;
|
||||
private _boundsSpineDirty = true;
|
||||
|
||||
constructor (options: SpineOptions | SkeletonData) {
|
||||
if (options instanceof SkeletonData) {
|
||||
options = {
|
||||
skeletonData: options,
|
||||
};
|
||||
}
|
||||
|
||||
constructor (options: SpineOptions | SpineFromOptions) {
|
||||
super();
|
||||
|
||||
const skeletonData = options instanceof SkeletonData ? options : options.skeletonData;
|
||||
if ("skeleton" in options)
|
||||
options = new.target.createOptions(options);
|
||||
|
||||
const { autoUpdate = true, boundsProvider, darkTint, skeletonData } = options;
|
||||
this.skeleton = new Skeleton(skeletonData);
|
||||
const animData = new AnimationStateData(skeletonData);
|
||||
this.state = new AnimationState(animData);
|
||||
this.autoUpdate = options?.autoUpdate ?? true;
|
||||
this.state = new AnimationState(new AnimationStateData(skeletonData));
|
||||
this.autoUpdate = autoUpdate;
|
||||
this.boundsProvider = boundsProvider;
|
||||
|
||||
// dark tint can be enabled by options, otherwise is enable if at least one slot has tint black
|
||||
this.darkTint = options?.darkTint === undefined
|
||||
this.darkTint = darkTint === undefined
|
||||
? this.skeleton.slots.some(slot => !!slot.data.setup.darkColor)
|
||||
: options?.darkTint;
|
||||
: darkTint;
|
||||
if (this.darkTint) this.slotMeshFactory = () => new DarkSlotMesh();
|
||||
|
||||
this.boundsProvider = options.boundsProvider;
|
||||
}
|
||||
|
||||
/** If {@link Spine.autoUpdate} is `false`, this method allows to update the AnimationState and the Skeleton with the given delta. */
|
||||
@ -861,7 +856,7 @@ export class Spine extends Container {
|
||||
public static readonly skeletonCache: Record<string, SkeletonData> = Object.create(null);
|
||||
|
||||
/**
|
||||
* Use this method to instantiate a Spine game object.
|
||||
* Get a convenient initialization configuration for your Spine game object.
|
||||
* Before instantiating a Spine game object, the skeleton (`.skel` or `.json`) and the atlas text files must be loaded into the Assets. For example:
|
||||
* ```
|
||||
* PIXI.Assets.add("sackData", "/assets/sack-pro.skel");
|
||||
@ -872,9 +867,9 @@ export class Spine extends Container {
|
||||
* `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
|
||||
*
|
||||
* @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
|
||||
* @returns {Spine} The Spine game object instantiated
|
||||
* @returns {SpineOptions} The configuration ready to be passed to the Spine constructor
|
||||
*/
|
||||
public static from ({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true, boundsProvider, allowMissingRegions }: SpineFromOptions) {
|
||||
public static createOptions ({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true, boundsProvider, allowMissingRegions }: SpineFromOptions): SpineOptions {
|
||||
const cacheKey = `${skeleton}-${atlas}-${scale}`;
|
||||
|
||||
let skeletonData = Spine.skeletonCache[cacheKey];
|
||||
@ -888,7 +883,25 @@ export class Spine extends Container {
|
||||
skeletonData = parser.readSkeletonData(skeletonAsset);
|
||||
Spine.skeletonCache[cacheKey] = skeletonData;
|
||||
}
|
||||
return new Spine({ skeletonData, darkTint, autoUpdate, boundsProvider });
|
||||
return { skeletonData, darkTint, autoUpdate, boundsProvider };
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use directly the Spine constructor or {@link createOptions} to make options and customize it to pass to the constructor
|
||||
* Before instantiating a Spine game object, the skeleton (`.skel` or `.json`) and the atlas text files must be loaded into the Assets. For example:
|
||||
* ```
|
||||
* PIXI.Assets.add("sackData", "/assets/sack-pro.skel");
|
||||
* PIXI.Assets.add("sackAtlas", "/assets/sack-pma.atlas");
|
||||
* await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
||||
* ```
|
||||
* Once a Spine game object is created, its skeleton data is cached into {@link Spine.skeletonCache} using the key:
|
||||
* `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
|
||||
*
|
||||
* @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
|
||||
* @returns {Spine} The Spine game object instantiated
|
||||
*/
|
||||
public static from (options: SpineFromOptions) {
|
||||
return new Spine(Spine.createOptions(options));
|
||||
}
|
||||
|
||||
public get tint (): number {
|
||||
|
||||
@ -29,21 +29,21 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy1 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2 });
|
||||
const spineboy1 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2 });
|
||||
|
||||
const spineboy2 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy2 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.SetupPoseBoundsProvider(),
|
||||
});
|
||||
|
||||
const spineboy3 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy3 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.SkinsAndAnimationBoundsProvider("portal", undefined, undefined, false),
|
||||
});
|
||||
|
||||
const spineboy4 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy4 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.SkinsAndAnimationBoundsProvider("portal", undefined, undefined, true),
|
||||
});
|
||||
|
||||
const spineboy5 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
const spineboy5 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
|
||||
boundsProvider: new spine.AABBRectangleBoundsProvider(-100, -100, 100, 100),
|
||||
});
|
||||
|
||||
|
||||
@ -98,7 +98,7 @@
|
||||
bounds;
|
||||
|
||||
constructor(bounds) {
|
||||
const spineboy = spine.Spine.from({
|
||||
const spineboy = new spine.Spine({
|
||||
atlas: "spineboyAtlas",
|
||||
skeleton: "spineboyData",
|
||||
scale: 0.125,
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({
|
||||
const spineboy = new spine.Spine({
|
||||
skeleton: "spineboyData",
|
||||
atlas: "spineboyAtlas",
|
||||
scale: 1,
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
await PIXI.Assets.load(["stretchymanData", "stretchymanAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const stretchyman = spine.Spine.from({skeleton: "stretchymanData", atlas: "stretchymanAtlas",
|
||||
const stretchyman = new spine.Spine({skeleton: "stretchymanData", atlas: "stretchymanAtlas",
|
||||
scale: 0.75,
|
||||
});
|
||||
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas", "spineboyData", "spineboyAtlas2"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
||||
const spineboy2 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
||||
const spineboy2 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
||||
spineboy.autoUpdate = false;
|
||||
spineboy2.autoUpdate = false;
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the Spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
await PIXI.Assets.load(["skelBase64", "atlasBase64"]);
|
||||
|
||||
// creating spine game object with base64 data
|
||||
const base64GameObject = spine.Spine.from({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
const base64GameObject = new spine.Spine({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
app.stage.addChild(base64GameObject);
|
||||
base64GameObject.state.setAnimation(0, "animation", true);
|
||||
base64GameObject.position.set(window.innerWidth / 3, window.innerHeight / 2);
|
||||
@ -90,7 +90,7 @@
|
||||
await PIXI.Assets.load(["skelBlob", "atlasBlob"]);
|
||||
|
||||
// creating spine game object
|
||||
const blobGameObject = spine.Spine.from({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
const blobGameObject = new spine.Spine({skeleton: "skelBase64", atlas: "atlasBase64" });
|
||||
app.stage.addChild(blobGameObject);
|
||||
blobGameObject.state.setAnimation(0, "animation", true);
|
||||
blobGameObject.position.set(window.innerWidth / 3 * 2, window.innerHeight / 2);
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["mixAndMatchData", "mixAndMatchAtlas"]);
|
||||
|
||||
// Create the Spine display object
|
||||
const mixAndMatch = spine.Spine.from({skeleton: "mixAndMatchData", atlas: "mixAndMatchAtlas",
|
||||
const mixAndMatch = new spine.Spine({skeleton: "mixAndMatchData", atlas: "mixAndMatchAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const sack = spine.Spine.from({skeleton: "sackData", atlas: "sackAtlas",
|
||||
const sack = new spine.Spine({skeleton: "sackData", atlas: "sackAtlas",
|
||||
scale: 0.2,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["girlData", "girlAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const girl = spine.Spine.from({skeleton: "girlData", atlas: "girlAtlas",
|
||||
const girl = new spine.Spine({skeleton: "girlData", atlas: "girlAtlas",
|
||||
scale: 0.2,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["snowglobeData", "snowglobeAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const snowglobe = spine.Spine.from({skeleton: "snowglobeData", atlas: "snowglobeAtlas",
|
||||
const snowglobe = new spine.Spine({skeleton: "snowglobeData", atlas: "snowglobeAtlas",
|
||||
scale: 0.25,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["cloudPotData", "cloudPotAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const cloudPot = spine.Spine.from({skeleton: "cloudPotData", atlas: "cloudPotAtlas",
|
||||
const cloudPot = new spine.Spine({skeleton: "cloudPotData", atlas: "cloudPotAtlas",
|
||||
scale: 0.25,
|
||||
});
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
PIXI.Assets.cache.set("spineboyAtlas", textureAtlas);
|
||||
|
||||
// creating spine game object
|
||||
const spineGO = spine.Spine.from({skeleton: "jsonSkel", atlas: "spineboyAtlas" });
|
||||
const spineGO = new spine.Spine({ skeleton: "jsonSkel", atlas: "spineboyAtlas" });
|
||||
spineGO.position.set(300, 300);
|
||||
app.stage.addChild(spineGO);
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas", "raptor_jaw"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.25 });
|
||||
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.25 });
|
||||
|
||||
// Set the default mix time to use when transitioning
|
||||
// from one animation to the next.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Application, Assets } from 'pixi.js';
|
||||
import { Spine } from '@esotericsoftware/spine-pixi-v8';
|
||||
import { Application, Assets } from 'pixi.js';
|
||||
|
||||
/** The PixiJS app Application instance, shared across the project */
|
||||
export const app = new Application();
|
||||
@ -25,7 +25,7 @@ async function init () {
|
||||
await Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = Spine.from({
|
||||
const spineboy = new Spine({
|
||||
atlas: "spineboyAtlas",
|
||||
skeleton: "spineboyData",
|
||||
scale: 0.5,
|
||||
|
||||
@ -43,7 +43,7 @@ import {
|
||||
SkeletonBinary,
|
||||
SkeletonBounds,
|
||||
SkeletonClipping,
|
||||
SkeletonData,
|
||||
type SkeletonData,
|
||||
SkeletonJson,
|
||||
Skin,
|
||||
type Slot,
|
||||
@ -292,7 +292,8 @@ const maskPool = new Pool<Graphics>(() => new Graphics);
|
||||
|
||||
/**
|
||||
* The class to instantiate a {@link Spine} game object in Pixi.
|
||||
* The static method {@link Spine.from} should be used to instantiate a Spine game object.
|
||||
* Create and customize the default configuration using the static method {@link Spine.createOptions},
|
||||
* then pass it to the constructor.
|
||||
*/
|
||||
export class Spine extends ViewContainer {
|
||||
// Pixi properties
|
||||
@ -384,35 +385,28 @@ export class Spine extends ViewContainer {
|
||||
}
|
||||
|
||||
private hasNeverUpdated = true;
|
||||
constructor (options: SpineOptions | SkeletonData) {
|
||||
if (options instanceof SkeletonData) {
|
||||
options = {
|
||||
skeletonData: options,
|
||||
};
|
||||
}
|
||||
|
||||
constructor (options: SpineOptions | SpineFromOptions) {
|
||||
super({});
|
||||
|
||||
if ("skeleton" in options)
|
||||
options = new.target.createOptions(options);
|
||||
|
||||
this.allowChildren = true;
|
||||
|
||||
const skeletonData = options instanceof SkeletonData ? options : options.skeletonData;
|
||||
|
||||
const { autoUpdate, boundsProvider, darkTint, skeletonData } = options;
|
||||
this.skeleton = new Skeleton(skeletonData);
|
||||
this.state = new AnimationState(new AnimationStateData(skeletonData));
|
||||
this.autoUpdate = options?.autoUpdate ?? true;
|
||||
this.autoUpdate = autoUpdate ?? true;
|
||||
this._boundsProvider = boundsProvider;
|
||||
|
||||
// dark tint can be enabled by options, otherwise is enable if at least one slot has tint black
|
||||
this.darkTint = options?.darkTint === undefined
|
||||
this.darkTint = darkTint === undefined
|
||||
? this.skeleton.slots.some(slot => !!slot.data.setup.darkColor)
|
||||
: options?.darkTint;
|
||||
: darkTint;
|
||||
|
||||
const slots = this.skeleton.slots;
|
||||
|
||||
for (let i = 0; i < slots.length; i++) {
|
||||
for (let i = 0; i < slots.length; i++)
|
||||
this.attachmentCacheData[i] = Object.create(null);
|
||||
}
|
||||
|
||||
this._boundsProvider = options.boundsProvider;
|
||||
}
|
||||
|
||||
/** If {@link Spine.autoUpdate} is `false`, this method allows to update the AnimationState and the Skeleton with the given delta. */
|
||||
@ -1065,6 +1059,55 @@ export class Spine extends ViewContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a convenient initialization configuration for your Spine game object.
|
||||
* Before instantiating a Spine game object, the skeleton (`.skel` or `.json`) and the atlas text files must be loaded into the {@link Assets}. For example:
|
||||
* ```
|
||||
* PIXI.Assets.add("sackData", "/assets/sack-pro.skel");
|
||||
* PIXI.Assets.add("sackAtlas", "/assets/sack-pma.atlas");
|
||||
* await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
||||
* ```
|
||||
* Once a Spine game object is created, its skeleton data is cached into {@link Cache} using the key:
|
||||
* `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
|
||||
*
|
||||
* @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
|
||||
* @returns {SpineOptions} The configuration ready to be passed to the Spine constructor
|
||||
*/
|
||||
static createOptions ({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true, boundsProvider, allowMissingRegions = false }: SpineFromOptions): SpineOptions {
|
||||
const cacheKey = `${skeleton}-${atlas}-${scale}`;
|
||||
|
||||
if (Cache.has(cacheKey)) {
|
||||
return {
|
||||
skeletonData: Cache.get<SkeletonData>(cacheKey),
|
||||
darkTint,
|
||||
autoUpdate,
|
||||
boundsProvider,
|
||||
};
|
||||
}
|
||||
|
||||
const atlasAsset = Assets.get<TextureAtlas>(atlas);
|
||||
const attachmentLoader = new AtlasAttachmentLoader(atlasAsset, allowMissingRegions);
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: json skeleton data is any
|
||||
const skeletonAsset = Assets.get<any | Uint8Array>(skeleton);
|
||||
const parser = skeletonAsset instanceof Uint8Array
|
||||
? new SkeletonBinary(attachmentLoader)
|
||||
: new SkeletonJson(attachmentLoader);
|
||||
|
||||
parser.scale = scale;
|
||||
const skeletonData = parser.readSkeletonData(skeletonAsset);
|
||||
|
||||
Cache.set(cacheKey, skeletonData);
|
||||
|
||||
return {
|
||||
skeletonData,
|
||||
darkTint,
|
||||
autoUpdate,
|
||||
boundsProvider,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use directly the Spine constructor or {@link createOptions} to make options and customize it to pass to the constructor
|
||||
* Use this method to instantiate a Spine game object.
|
||||
* Before instantiating a Spine game object, the skeleton (`.skel` or `.json`) and the atlas text files must be loaded into the Assets. For example:
|
||||
* ```
|
||||
@ -1078,36 +1121,7 @@ export class Spine extends ViewContainer {
|
||||
* @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
|
||||
* @returns {Spine} The Spine game object instantiated
|
||||
*/
|
||||
static from ({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true, boundsProvider, allowMissingRegions = false }: SpineFromOptions) {
|
||||
const cacheKey = `${skeleton}-${atlas}-${scale}`;
|
||||
|
||||
if (Cache.has(cacheKey)) {
|
||||
return new Spine({
|
||||
skeletonData: Cache.get<SkeletonData>(cacheKey),
|
||||
darkTint,
|
||||
autoUpdate,
|
||||
boundsProvider,
|
||||
});
|
||||
}
|
||||
|
||||
const skeletonAsset = Assets.get<any | Uint8Array>(skeleton);
|
||||
|
||||
const atlasAsset = Assets.get<TextureAtlas>(atlas);
|
||||
const attachmentLoader = new AtlasAttachmentLoader(atlasAsset, allowMissingRegions);
|
||||
const parser = skeletonAsset instanceof Uint8Array
|
||||
? new SkeletonBinary(attachmentLoader)
|
||||
: new SkeletonJson(attachmentLoader);
|
||||
|
||||
parser.scale = scale;
|
||||
const skeletonData = parser.readSkeletonData(skeletonAsset);
|
||||
|
||||
Cache.set(cacheKey, skeletonData);
|
||||
|
||||
return new Spine({
|
||||
skeletonData,
|
||||
darkTint,
|
||||
autoUpdate,
|
||||
boundsProvider,
|
||||
});
|
||||
static from (options: SpineFromOptions) {
|
||||
return new Spine(Spine.createOptions(options));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user