[ts][player] Closes #2536, deprecate jsonURL, skelURL, and atlasURL in favor of skeleton and atlas fields.

This commit is contained in:
Mario Zechner 2024-06-04 10:57:33 +02:00
parent eaaec84aa9
commit a74a5754b4
8 changed files with 115 additions and 95 deletions

View File

@ -113,6 +113,7 @@
## C# ## C#
- **Additions** - **Additions**
- Added [`TrackEntry.AlphaAttachmentThreshold`](http://esotericsoftware.com/spine-api-reference#TrackEntry-alphaAttachmentThreshold). - Added [`TrackEntry.AlphaAttachmentThreshold`](http://esotericsoftware.com/spine-api-reference#TrackEntry-alphaAttachmentThreshold).
- **Breaking changes** - **Breaking changes**
@ -176,6 +177,7 @@
- **Restructuring (Non-Breaking)** - **Restructuring (Non-Breaking)**
### XNA/MonoGame ### XNA/MonoGame
- **Additions** - **Additions**
- Apply external movement to physics: If you are not directly modifying `Skeleton.X` or `Skeleton.Y`, you can apply external game object movement to skeleton physics as follows: - Apply external movement to physics: If you are not directly modifying `Skeleton.X` or `Skeleton.Y`, you can apply external game object movement to skeleton physics as follows:
Add a `Vector2 lastPosition;` member variable to your class interacting with the skeleton. Then call e.g. the following code each frame: Add a `Vector2 lastPosition;` member variable to your class interacting with the skeleton. Then call e.g. the following code each frame:
@ -263,6 +265,8 @@
- Added physics support - Added physics support
- Added `scale` field to configuration which defines the scale to load the skeleton at - Added `scale` field to configuration which defines the scale to load the skeleton at
- Added `updateWorldTransform` field to configuration which expects a function that updates the skeleton. Defaults to player.skeleton.updateWorldTransform(spine.Physics.update) - Added `updateWorldTransform` field to configuration which expects a function that updates the skeleton. Defaults to player.skeleton.updateWorldTransform(spine.Physics.update)
- Added `skeleton` to `SpinePlayerConfig` to specify the URL of the skeleton .json or .skel file. Deprecated `jsonURL` and `binaryURL`. The old fields can still be used, but will be removed in Spine 4.3
- Added `atlas` to `SpinePlayerConfig` to specify the URL of the .atlas file. Deprecated `atlasURL`. The old field can still be used, but will be removed in Spine 4.3.
### Pixi ### Pixi

View File

@ -24,8 +24,8 @@
function createPlayer() { function createPlayer() {
return new spine.SpinePlayer("container", { return new spine.SpinePlayer("container", {
skelUrl: "assets/spineboy-pro.skel", skeleton: "assets/spineboy-pro.skel",
atlasUrl: "assets/spineboy-pma.atlas", atlas: "assets/spineboy-pma.atlas",
animation: "run", animation: "run",
premultipliedAlpha: true, premultipliedAlpha: true,
backgroundColor: "#cccccc", backgroundColor: "#cccccc",

View File

@ -1,24 +1,27 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="../dist/iife/spine-player.js"></script> <script src="../dist/iife/spine-player.js"></script>
<link rel="stylesheet" href="../../index.css" /> <link rel="stylesheet" href="../../index.css" />
<title>Spine Player Editor</title> <title>Spine Player Editor</title>
</head> </head>
<body class="flex flex-col w-full h-screen items-center">
<body class="flex flex-col w-full h-screen items-center">
<div id="editor" class="w-full h-full flex-grow"></div> <div id="editor" class="w-full h-full flex-grow"></div>
<script> <script>
var code = var code =
'<script src="https://unpkg.com/@esotericsoftware/spine-player@4.1.*/dist/iife/spine-player.js"></' + '<script src="https://unpkg.com/@esotericsoftware/spine-player@4.2.*/dist/iife/spine-player.js"></' +
'script>\n<link rel="stylesheet" href="https://unpkg.com/@esotericsoftware/spine-player@4.1.*/dist/spine-player.css">\n\n<div id="player-container" style="width: 100%; height: 100vh;"></div>\n\n<script>\nnew spine.SpinePlayer("player-container", {\n jsonUrl: "http://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy-pro.json",\n atlasUrl: "http://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy.atlas"\n});\n</' + 'script>\n<link rel="stylesheet" href="https://unpkg.com/@esotericsoftware/spine-player@4.1.*/dist/spine-player.css">\n\n<div id="player-container" style="width: 100%; height: 100vh;"></div>\n\n<script>\nnew spine.SpinePlayer("player-container", {\n skeleton: "http://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy-pro.json",\n atlas: "http://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy.atlas"\n});\n</' +
"script>".trim(); "script>".trim();
spine.SpinePlayerEditor.DEFAULT_CODE = code; spine.SpinePlayerEditor.DEFAULT_CODE = code;
var player = new spine.SpinePlayerEditor( var player = new spine.SpinePlayerEditor(
document.getElementById("editor") document.getElementById("editor")
); );
</script> </script>
</body> </body>
</html> </html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -24,8 +24,8 @@
// Creates a new spine player. The debugRender option enables // Creates a new spine player. The debugRender option enables
// rendering of viewports and padding for debugging purposes. // rendering of viewports and padding for debugging purposes.
new spine.SpinePlayer("container", { new spine.SpinePlayer("container", {
skelUrl: "assets/spineboy-pro.skel", skeleton: "assets/spineboy-pro.skel",
atlasUrl: "assets/spineboy-pma.atlas", atlas: "assets/spineboy-pma.atlas",
animation: "run", animation: "run",
premultipliedAlpha: true, premultipliedAlpha: true,
backgroundColor: "#cccccc", backgroundColor: "#cccccc",
@ -42,8 +42,8 @@
// so content from the website shines through. Hides the controls. // so content from the website shines through. Hides the controls.
// Instead, the user can control the animation via buttons. // Instead, the user can control the animation via buttons.
var jsControlledPlayer = new spine.SpinePlayer("container-raptor", { var jsControlledPlayer = new spine.SpinePlayer("container-raptor", {
jsonUrl: "assets/raptor-pro.json", skeleton: "assets/raptor-pro.json",
atlasUrl: "assets/raptor-pma.atlas", atlas: "assets/raptor-pma.atlas",
animation: "walk", animation: "walk",
showControls: false, showControls: false,
premultipliedAlpha: true, premultipliedAlpha: true,

View File

@ -1,21 +1,23 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="../dist/iife/spine-player.js"></script> <script src="../dist/iife/spine-player.js"></script>
<link rel="stylesheet" href="../dist/spine-player.css" /> <link rel="stylesheet" href="../dist/spine-player.css" />
<link rel="stylesheet" href="../../index.css" /> <link rel="stylesheet" href="../../index.css" />
</head> </head>
<body style="margin: 0">
<body style="margin: 0">
<span class="overlay">Drag the swinging lady</span> <span class="overlay">Drag the swinging lady</span>
<div id="player" style="width: 100%; height: 100vh"></div> <div id="player" style="width: 100%; height: 100vh"></div>
<script> <script>
var mouse = new spine.Vector3(), var mouse = new spine.Vector3(),
last = new spine.Vector3(); last = new spine.Vector3();
new spine.SpinePlayer("player", { new spine.SpinePlayer("player", {
skelUrl: "assets/celestial-circus-pro.skel", skeleton: "assets/celestial-circus-pro.skel",
atlasUrl: "assets/celestial-circus-pma.atlas", url: "assets/celestial-circus-pma.atlas",
showControls: true, showControls: true,
animation: "swing", animation: "swing",
success: (player) => { success: (player) => {
@ -43,5 +45,6 @@
}, },
}); });
</script> </script>
</body> </body>
</html> </html>

View File

@ -31,23 +31,29 @@ import { Animation, AnimationState, AnimationStateData, AtlasAttachmentLoader, B
import { AssetManager, GLTexture, Input, LoadingScreen, ManagedWebGLRenderingContext, ResizeMode, SceneRenderer, Vector3 } from "@esotericsoftware/spine-webgl" import { AssetManager, GLTexture, Input, LoadingScreen, ManagedWebGLRenderingContext, ResizeMode, SceneRenderer, Vector3 } from "@esotericsoftware/spine-webgl"
export interface SpinePlayerConfig { export interface SpinePlayerConfig {
/* The URL of the skeleton JSON file (.json). Undefined if binaryUrl is given. */ /* The URL of the skeleton JSON (.json) or binary (.skel) file */
skeleton?: string;
/* @deprecated Use skeleton instead. The URL of the skeleton JSON file (.json). Undefined if binaryUrl is given. */
jsonUrl?: string jsonUrl?: string
/* Optional: The name of a field in the JSON that holds the skeleton data. Default: none */ /* Optional: The name of a field in the JSON that holds the skeleton data. Default: none */
jsonField?: string jsonField?: string
/* The URL of the skeleton binary file (.skel). Undefined if jsonUrl is given. */ /* @deprecated Use skeleton instead. The URL of the skeleton binary file (.skel). Undefined if jsonUrl is given. */
binaryUrl?: string binaryUrl?: string
/* The scale when loading the skeleton data. Default: 1 */ /* The scale when loading the skeleton data. Default: 1 */
scale?: number scale?: number
/* The URL of the skeleton atlas file (.atlas). Atlas page images are automatically resolved. */ /* @deprecated Use atlas instead. The URL of the skeleton atlas file (.atlas). Atlas page images are automatically resolved. */
atlasUrl?: string atlasUrl?: string
/* Raw data URIs, mapping a path to base64 encoded raw data. When player's asset manager resolves the jsonUrl, binaryUrl, /* The URL of the skeleton atlas file (.atlas). Atlas page images are automatically resolved. */
atlasUrl, or the image paths referenced in the atlas, it will first look for that path in the raw data URIs. This atlas?: string;
/* Raw data URIs, mapping a path to base64 encoded raw data. When player's asset manager resolves the skeleton,
atlas, or the image paths referenced in the atlas, it will first look for that path in the raw data URIs. This
allows embedding assets directly in HTML/JS. Default: none */ allows embedding assets directly in HTML/JS. Default: none */
rawDataURIs?: StringMap<string> rawDataURIs?: StringMap<string>
@ -285,10 +291,14 @@ export class SpinePlayer implements Disposable {
private validateConfig (config: SpinePlayerConfig) { private validateConfig (config: SpinePlayerConfig) {
if (!config) throw new Error("A configuration object must be passed to to new SpinePlayer()."); if (!config) throw new Error("A configuration object must be passed to to new SpinePlayer().");
if ((config as any).skelUrl) config.binaryUrl = (config as any).skelUrl; if (!config.skeleton && !config.jsonUrl && !config.binaryUrl) throw new Error("A URL must be specified for the skeleton JSON or binary file.");
if (!config.jsonUrl && !config.binaryUrl) throw new Error("A URL must be specified for the skeleton JSON or binary file.");
if (!config.scale) config.scale = 1; if (!config.scale) config.scale = 1;
if (!config.atlasUrl) throw new Error("A URL must be specified for the atlas file."); if (!config.atlas && !config.atlasUrl) throw new Error("A URL must be specified for the atlas file.");
if (config.jsonUrl && !config.skeleton) config.skeleton = config.jsonUrl;
if (config.binaryUrl && !config.skeleton) config.skeleton = config.binaryUrl;
if (config.atlasUrl && !config.atlas) config.atlas = config.atlasUrl;
if (!config.backgroundColor) config.backgroundColor = config.alpha ? "00000000" : "000000"; if (!config.backgroundColor) config.backgroundColor = config.alpha ? "00000000" : "000000";
if (!config.fullScreenBackgroundColor) config.fullScreenBackgroundColor = config.backgroundColor; if (!config.fullScreenBackgroundColor) config.fullScreenBackgroundColor = config.backgroundColor;
if (config.backgroundImage && !config.backgroundImage.url) config.backgroundImage = undefined; if (config.backgroundImage && !config.backgroundImage.url) config.backgroundImage = undefined;
@ -346,11 +356,11 @@ export class SpinePlayer implements Disposable {
for (let path in config.rawDataURIs) for (let path in config.rawDataURIs)
this.assetManager.setRawDataURI(path, config.rawDataURIs[path]); this.assetManager.setRawDataURI(path, config.rawDataURIs[path]);
} }
if (config.jsonUrl) if (config.skeleton!.endsWith(".json"))
this.assetManager.loadJson(config.jsonUrl); this.assetManager.loadJson(config.skeleton!);
else else
this.assetManager.loadBinary(config.binaryUrl!); this.assetManager.loadBinary(config.skeleton!);
this.assetManager.loadTextureAtlas(config.atlasUrl!); this.assetManager.loadTextureAtlas(config.atlas!);
if (config.backgroundImage) this.assetManager.loadTexture(config.backgroundImage.url); if (config.backgroundImage) this.assetManager.loadTexture(config.backgroundImage.url);
// Setup the UI elements. // Setup the UI elements.
@ -442,7 +452,7 @@ export class SpinePlayer implements Disposable {
let config = this.config; let config = this.config;
// Configure filtering, don't use mipmaps in WebGL1 if the atlas page is non-POT // Configure filtering, don't use mipmaps in WebGL1 if the atlas page is non-POT
let atlas = this.assetManager!.require(config.atlasUrl!) as TextureAtlas; let atlas = this.assetManager!.require(config.atlas!) as TextureAtlas;
let gl = this.context!.gl, anisotropic = gl.getExtension("EXT_texture_filter_anisotropic"); let gl = this.context!.gl, anisotropic = gl.getExtension("EXT_texture_filter_anisotropic");
let isWebGL1 = gl.getParameter(gl.VERSION).indexOf("WebGL 1.0") != -1; let isWebGL1 = gl.getParameter(gl.VERSION).indexOf("WebGL 1.0") != -1;
for (let page of atlas.pages) { for (let page of atlas.pages) {
@ -466,8 +476,8 @@ export class SpinePlayer implements Disposable {
let skeletonData: SkeletonData; let skeletonData: SkeletonData;
try { try {
let loader: any, data: any, attachmentLoader = new AtlasAttachmentLoader(atlas); let loader: any, data: any, attachmentLoader = new AtlasAttachmentLoader(atlas);
if (config.jsonUrl) { if (config.skeleton!.endsWith(".json")) {
data = this.assetManager!.remove(config.jsonUrl); data = this.assetManager!.remove(config.skeleton!);
if (!data) throw new Error("Empty JSON data."); if (!data) throw new Error("Empty JSON data.");
if (config.jsonField) { if (config.jsonField) {
data = data[config.jsonField]; data = data[config.jsonField];
@ -475,7 +485,7 @@ export class SpinePlayer implements Disposable {
} }
loader = new SkeletonJson(attachmentLoader); loader = new SkeletonJson(attachmentLoader);
} else { } else {
data = this.assetManager!.remove(config.binaryUrl!); data = this.assetManager!.remove(config.skeleton!);
loader = new SkeletonBinary(attachmentLoader); loader = new SkeletonBinary(attachmentLoader);
} }
loader.scale = config.scale; loader.scale = config.scale;