mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +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
|
// 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(),
|
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),
|
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),
|
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),
|
boundsProvider: new spine.AABBRectangleBoundsProvider(-100, -100, 100, 100),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,7 @@
|
|||||||
bounds;
|
bounds;
|
||||||
|
|
||||||
constructor(bounds) {
|
constructor(bounds) {
|
||||||
const spineboy = spine.Spine.from({
|
const spineboy = new spine.Spine({
|
||||||
atlas: "spineboyAtlas",
|
atlas: "spineboyAtlas",
|
||||||
skeleton: "spineboyData",
|
skeleton: "spineboyData",
|
||||||
scale: 0.125,
|
scale: 0.125,
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
await PIXI.Assets.load(["stretchymanData", "stretchymanAtlas"]);
|
await PIXI.Assets.load(["stretchymanData", "stretchymanAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.75,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the Spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
await PIXI.Assets.load(["skelBase64", "atlasBase64"]);
|
await PIXI.Assets.load(["skelBase64", "atlasBase64"]);
|
||||||
|
|
||||||
// creating spine game object with base64 data
|
// 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);
|
app.stage.addChild(base64GameObject);
|
||||||
base64GameObject.state.setAnimation(0, "animation", true);
|
base64GameObject.state.setAnimation(0, "animation", true);
|
||||||
base64GameObject.position.set(window.innerWidth / 3, window.innerHeight / 2);
|
base64GameObject.position.set(window.innerWidth / 3, window.innerHeight / 2);
|
||||||
@ -91,7 +91,7 @@
|
|||||||
await PIXI.Assets.load(["skelBlob", "atlasBlob"]);
|
await PIXI.Assets.load(["skelBlob", "atlasBlob"]);
|
||||||
|
|
||||||
// creating spine game object
|
// 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);
|
app.stage.addChild(blobGameObject);
|
||||||
blobGameObject.state.setAnimation(0, "animation", true);
|
blobGameObject.state.setAnimation(0, "animation", true);
|
||||||
blobGameObject.position.set(window.innerWidth / 3 * 2, window.innerHeight / 2);
|
blobGameObject.position.set(window.innerWidth / 3 * 2, window.innerHeight / 2);
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["mixAndMatchData", "mixAndMatchAtlas"]);
|
await PIXI.Assets.load(["mixAndMatchData", "mixAndMatchAtlas"]);
|
||||||
|
|
||||||
// Create the Spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.2,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["girlData", "girlAtlas"]);
|
await PIXI.Assets.load(["girlData", "girlAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.2,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["snowglobeData", "snowglobeAtlas"]);
|
await PIXI.Assets.load(["snowglobeData", "snowglobeAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.25,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["cloudPotData", "cloudPotAtlas"]);
|
await PIXI.Assets.load(["cloudPotData", "cloudPotAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.25,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
PIXI.Assets.cache.set("spineboyAtlas", textureAtlas);
|
PIXI.Assets.cache.set("spineboyAtlas", textureAtlas);
|
||||||
|
|
||||||
// creating spine game object
|
// 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);
|
spineGO.position.set(300, 300);
|
||||||
app.stage.addChild(spineGO);
|
app.stage.addChild(spineGO);
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.25,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Application, Assets } from 'pixi.js';
|
|
||||||
import { Spine } from '@esotericsoftware/spine-pixi-v7';
|
import { Spine } from '@esotericsoftware/spine-pixi-v7';
|
||||||
|
import { Application, Assets } from 'pixi.js';
|
||||||
|
|
||||||
/** The PixiJS app Application instance, shared across the project */
|
/** The PixiJS app Application instance, shared across the project */
|
||||||
export const app = new Application<HTMLCanvasElement>({
|
export const app = new Application<HTMLCanvasElement>({
|
||||||
@ -23,7 +23,8 @@ async function init () {
|
|||||||
await Assets.load(["spineboyData", "spineboyAtlas"]);
|
await Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// Create the spine display object
|
||||||
const spineboy = Spine.from("spineboyData", "spineboyAtlas", {
|
const spineboy = new Spine({
|
||||||
|
skeleton: "spineboyData", atlas: "spineboyAtlas",
|
||||||
scale: 0.5,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ import {
|
|||||||
Skeleton,
|
Skeleton,
|
||||||
SkeletonBinary,
|
SkeletonBinary,
|
||||||
SkeletonClipping,
|
SkeletonClipping,
|
||||||
SkeletonData,
|
type SkeletonData,
|
||||||
SkeletonJson,
|
SkeletonJson,
|
||||||
Skin,
|
Skin,
|
||||||
Utils,
|
Utils,
|
||||||
@ -247,7 +247,8 @@ export class SkinsAndAnimationBoundsProvider
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The class to instantiate a {@link Spine} game object in Pixi.
|
* 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 {
|
export class Spine extends Container {
|
||||||
/** The skeleton for this Spine game object. */
|
/** The skeleton for this Spine game object. */
|
||||||
@ -328,29 +329,23 @@ export class Spine extends Container {
|
|||||||
private _boundsSpineID = -1;
|
private _boundsSpineID = -1;
|
||||||
private _boundsSpineDirty = true;
|
private _boundsSpineDirty = true;
|
||||||
|
|
||||||
constructor (options: SpineOptions | SkeletonData) {
|
constructor (options: SpineOptions | SpineFromOptions) {
|
||||||
if (options instanceof SkeletonData) {
|
|
||||||
options = {
|
|
||||||
skeletonData: options,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
super();
|
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);
|
this.skeleton = new Skeleton(skeletonData);
|
||||||
const animData = new AnimationStateData(skeletonData);
|
this.state = new AnimationState(new AnimationStateData(skeletonData));
|
||||||
this.state = new AnimationState(animData);
|
this.autoUpdate = autoUpdate;
|
||||||
this.autoUpdate = options?.autoUpdate ?? true;
|
this.boundsProvider = boundsProvider;
|
||||||
|
|
||||||
// dark tint can be enabled by options, otherwise is enable if at least one slot has tint black
|
// 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)
|
? this.skeleton.slots.some(slot => !!slot.data.setup.darkColor)
|
||||||
: options?.darkTint;
|
: darkTint;
|
||||||
if (this.darkTint) this.slotMeshFactory = () => new DarkSlotMesh();
|
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. */
|
/** 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);
|
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:
|
* 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("sackData", "/assets/sack-pro.skel");
|
||||||
@ -872,9 +867,9 @@ export class Spine extends Container {
|
|||||||
* `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
|
* `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
|
||||||
*
|
*
|
||||||
* @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
|
* @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}`;
|
const cacheKey = `${skeleton}-${atlas}-${scale}`;
|
||||||
|
|
||||||
let skeletonData = Spine.skeletonCache[cacheKey];
|
let skeletonData = Spine.skeletonCache[cacheKey];
|
||||||
@ -888,7 +883,25 @@ export class Spine extends Container {
|
|||||||
skeletonData = parser.readSkeletonData(skeletonAsset);
|
skeletonData = parser.readSkeletonData(skeletonAsset);
|
||||||
Spine.skeletonCache[cacheKey] = skeletonData;
|
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 {
|
public get tint (): number {
|
||||||
|
|||||||
@ -29,21 +29,21 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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(),
|
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),
|
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),
|
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),
|
boundsProvider: new spine.AABBRectangleBoundsProvider(-100, -100, 100, 100),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -98,7 +98,7 @@
|
|||||||
bounds;
|
bounds;
|
||||||
|
|
||||||
constructor(bounds) {
|
constructor(bounds) {
|
||||||
const spineboy = spine.Spine.from({
|
const spineboy = new spine.Spine({
|
||||||
atlas: "spineboyAtlas",
|
atlas: "spineboyAtlas",
|
||||||
skeleton: "spineboyData",
|
skeleton: "spineboyData",
|
||||||
scale: 0.125,
|
scale: 0.125,
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// Create the spine display object
|
||||||
const spineboy = spine.Spine.from({
|
const spineboy = new spine.Spine({
|
||||||
skeleton: "spineboyData",
|
skeleton: "spineboyData",
|
||||||
atlas: "spineboyAtlas",
|
atlas: "spineboyAtlas",
|
||||||
scale: 1,
|
scale: 1,
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
await PIXI.Assets.load(["stretchymanData", "stretchymanAtlas"]);
|
await PIXI.Assets.load(["stretchymanData", "stretchymanAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.75,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -32,8 +32,8 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas", "spineboyData", "spineboyAtlas2"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas", "spineboyData", "spineboyAtlas2"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// Create the spine display object
|
||||||
const spineboy = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
const spineboy = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
||||||
const spineboy2 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
const spineboy2 = new spine.Spine({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: 0.5 });
|
||||||
spineboy.autoUpdate = false;
|
spineboy.autoUpdate = false;
|
||||||
spineboy2.autoUpdate = false;
|
spineboy2.autoUpdate = false;
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the Spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@
|
|||||||
await PIXI.Assets.load(["skelBase64", "atlasBase64"]);
|
await PIXI.Assets.load(["skelBase64", "atlasBase64"]);
|
||||||
|
|
||||||
// creating spine game object with base64 data
|
// 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);
|
app.stage.addChild(base64GameObject);
|
||||||
base64GameObject.state.setAnimation(0, "animation", true);
|
base64GameObject.state.setAnimation(0, "animation", true);
|
||||||
base64GameObject.position.set(window.innerWidth / 3, window.innerHeight / 2);
|
base64GameObject.position.set(window.innerWidth / 3, window.innerHeight / 2);
|
||||||
@ -90,7 +90,7 @@
|
|||||||
await PIXI.Assets.load(["skelBlob", "atlasBlob"]);
|
await PIXI.Assets.load(["skelBlob", "atlasBlob"]);
|
||||||
|
|
||||||
// creating spine game object
|
// 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);
|
app.stage.addChild(blobGameObject);
|
||||||
blobGameObject.state.setAnimation(0, "animation", true);
|
blobGameObject.state.setAnimation(0, "animation", true);
|
||||||
blobGameObject.position.set(window.innerWidth / 3 * 2, window.innerHeight / 2);
|
blobGameObject.position.set(window.innerWidth / 3 * 2, window.innerHeight / 2);
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["mixAndMatchData", "mixAndMatchAtlas"]);
|
await PIXI.Assets.load(["mixAndMatchData", "mixAndMatchAtlas"]);
|
||||||
|
|
||||||
// Create the Spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.2,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["girlData", "girlAtlas"]);
|
await PIXI.Assets.load(["girlData", "girlAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.2,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["snowglobeData", "snowglobeAtlas"]);
|
await PIXI.Assets.load(["snowglobeData", "snowglobeAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.25,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["cloudPotData", "cloudPotAtlas"]);
|
await PIXI.Assets.load(["cloudPotData", "cloudPotAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.25,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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,
|
scale: 0.5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
PIXI.Assets.cache.set("spineboyAtlas", textureAtlas);
|
PIXI.Assets.cache.set("spineboyAtlas", textureAtlas);
|
||||||
|
|
||||||
// creating spine game object
|
// 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);
|
spineGO.position.set(300, 300);
|
||||||
app.stage.addChild(spineGO);
|
app.stage.addChild(spineGO);
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas", "raptor_jaw"]);
|
await PIXI.Assets.load(["spineboyData", "spineboyAtlas", "raptor_jaw"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// 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
|
// Set the default mix time to use when transitioning
|
||||||
// from one animation to the next.
|
// from one animation to the next.
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Application, Assets } from 'pixi.js';
|
|
||||||
import { Spine } from '@esotericsoftware/spine-pixi-v8';
|
import { Spine } from '@esotericsoftware/spine-pixi-v8';
|
||||||
|
import { Application, Assets } from 'pixi.js';
|
||||||
|
|
||||||
/** The PixiJS app Application instance, shared across the project */
|
/** The PixiJS app Application instance, shared across the project */
|
||||||
export const app = new Application();
|
export const app = new Application();
|
||||||
@ -25,7 +25,7 @@ async function init () {
|
|||||||
await Assets.load(["spineboyData", "spineboyAtlas"]);
|
await Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||||
|
|
||||||
// Create the spine display object
|
// Create the spine display object
|
||||||
const spineboy = Spine.from({
|
const spineboy = new Spine({
|
||||||
atlas: "spineboyAtlas",
|
atlas: "spineboyAtlas",
|
||||||
skeleton: "spineboyData",
|
skeleton: "spineboyData",
|
||||||
scale: 0.5,
|
scale: 0.5,
|
||||||
|
|||||||
@ -43,7 +43,7 @@ import {
|
|||||||
SkeletonBinary,
|
SkeletonBinary,
|
||||||
SkeletonBounds,
|
SkeletonBounds,
|
||||||
SkeletonClipping,
|
SkeletonClipping,
|
||||||
SkeletonData,
|
type SkeletonData,
|
||||||
SkeletonJson,
|
SkeletonJson,
|
||||||
Skin,
|
Skin,
|
||||||
type Slot,
|
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 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 {
|
export class Spine extends ViewContainer {
|
||||||
// Pixi properties
|
// Pixi properties
|
||||||
@ -384,35 +385,28 @@ export class Spine extends ViewContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private hasNeverUpdated = true;
|
private hasNeverUpdated = true;
|
||||||
constructor (options: SpineOptions | SkeletonData) {
|
constructor (options: SpineOptions | SpineFromOptions) {
|
||||||
if (options instanceof SkeletonData) {
|
|
||||||
options = {
|
|
||||||
skeletonData: options,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
|
if ("skeleton" in options)
|
||||||
|
options = new.target.createOptions(options);
|
||||||
|
|
||||||
this.allowChildren = true;
|
this.allowChildren = true;
|
||||||
|
|
||||||
const skeletonData = options instanceof SkeletonData ? options : options.skeletonData;
|
const { autoUpdate, boundsProvider, darkTint, skeletonData } = options;
|
||||||
|
|
||||||
this.skeleton = new Skeleton(skeletonData);
|
this.skeleton = new Skeleton(skeletonData);
|
||||||
this.state = new AnimationState(new AnimationStateData(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
|
// 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)
|
? this.skeleton.slots.some(slot => !!slot.data.setup.darkColor)
|
||||||
: options?.darkTint;
|
: darkTint;
|
||||||
|
|
||||||
const slots = this.skeleton.slots;
|
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.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. */
|
/** 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.
|
* 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:
|
* 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}
|
* @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
|
||||||
* @returns {Spine} The Spine game object instantiated
|
* @returns {Spine} The Spine game object instantiated
|
||||||
*/
|
*/
|
||||||
static from ({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true, boundsProvider, allowMissingRegions = false }: SpineFromOptions) {
|
static from (options: SpineFromOptions) {
|
||||||
const cacheKey = `${skeleton}-${atlas}-${scale}`;
|
return new Spine(Spine.createOptions(options));
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user