[ts] Modularize player, add package.json files, fix up module paths.

This commit is contained in:
Mario Zechner 2021-08-25 21:00:17 +02:00
parent 79f0abf765
commit 17c342ac61
33 changed files with 1251 additions and 10010 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -61,6 +61,14 @@
"node": ">=6.9.0"
}
},
"node_modules/@esotericsoftware/spine-canvas": {
"resolved": "spine-canvas",
"link": true
},
"node_modules/@esotericsoftware/spine-core": {
"resolved": "spine-core",
"link": true
},
"node_modules/@esotericsoftware/spine-webgl": {
"resolved": "spine-webgl",
"link": true
@ -5398,13 +5406,17 @@
"spine-canvas": {
"name": "@esotericsoftware/spine-canvas",
"version": "4.0.1",
"extraneous": true,
"license": "LicenseRef-LICENSE"
"license": "LicenseRef-LICENSE",
"devDependencies": {
"npx": "^10.2.2",
"rollup": "^2.56.2",
"rollup-plugin-dts": "^3.0.2",
"typescript": "^4.3.5"
}
},
"spine-core": {
"name": "@esotericsoftware/spine-core",
"version": "4.0.1",
"extraneous": true,
"license": "LicenseRef-LICENSE"
},
"spine-webgl": {
@ -5443,6 +5455,18 @@
"js-tokens": "^4.0.0"
}
},
"@esotericsoftware/spine-canvas": {
"version": "file:spine-canvas",
"requires": {
"npx": "^10.2.2",
"rollup": "^2.56.2",
"rollup-plugin-dts": "^3.0.2",
"typescript": "^4.3.5"
}
},
"@esotericsoftware/spine-core": {
"version": "file:spine-core"
},
"@esotericsoftware/spine-webgl": {
"version": "file:spine-webgl"
},

View File

@ -3,7 +3,11 @@
"version": "4.0.1",
"description": "The official Spine Runtimes for the web.",
"scripts": {
"build": "npx tsc -b --clean; tsc -b; npx rollup -c rollup.config.js --sourcemap;"
"build": "rm -rf build && npm run build:core && npm run build:canvas && npm run build:webgl && npm run build:player",
"build:core": "npx esbuild --bundle spine-core/src/index.ts --tsconfig=spine-core/tsconfig.json --minify --sourcemap --outfile=build/spine-core.js --format=iife --global-name=\"spine\"",
"build:canvas": "npx esbuild --bundle spine-canvas/src/index.ts --tsconfig=spine-canvas/tsconfig.json --minify --sourcemap --outfile=build/spine-canvas.js --format=iife --global-name=\"spine\"",
"build:webgl": "npx esbuild --bundle spine-webgl/src/index.ts --tsconfig=spine-webgl/tsconfig.json --minify --sourcemap --outfile=build/spine-webgl.js --format=iife --global-name=\"spine\"",
"build:player": "npx esbuild --bundle spine-player/src/index.ts --tsconfig=spine-player/tsconfig.json --sourcemap --outfile=build/spine-player.js --format=iife --global-name=\"spine\""
},
"repository": {
"type": "git",

View File

@ -3,6 +3,10 @@
"version": "4.0.1",
"description": "The official Spine Runtimes for the web.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/**/*"
],
"scripts": {},
"repository": {
"type": "git",

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { AssetManagerBase, Downloader } from "spine-core";
import { AssetManagerBase, Downloader } from "@esotericsoftware/spine-core"
import { CanvasTexture } from "./CanvasTexture";
export class AssetManager extends AssetManagerBase {

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Texture, TextureFilter, TextureWrap } from "spine-core";
import { Texture, TextureFilter, TextureWrap } from "@esotericsoftware/spine-core";
export class CanvasTexture extends Texture {
constructor(image: HTMLImageElement) {

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Utils, Color, Skeleton, RegionAttachment, TextureAtlasRegion, BlendMode, MeshAttachment, Slot } from "spine-core";
import { Utils, Color, Skeleton, RegionAttachment, TextureAtlasRegion, BlendMode, MeshAttachment, Slot } from "@esotericsoftware/spine-core";
import { CanvasTexture } from "./CanvasTexture";
export class SkeletonRenderer {

View File

@ -2,7 +2,7 @@ export * from "./AssetManager";
export * from "./CanvasTexture";
export * from "./SkeletonRenderer";
export * from "spine-core";
export * from "@esotericsoftware/spine-core"
// Before modularization, we would expose spine-core on the global
// `spine` object, and spine-canvas on the global `spine.canvas` object.
@ -23,9 +23,5 @@ export * from "spine-core";
//
// This will break if esbuild renames the variable `src_exports` pointing to
// the exports object.
declare global {
var spine: any;
}
let exports = eval("src_exports");
exports.canvas = exports;
if (exports) exports.canvas = exports;

View File

@ -5,7 +5,7 @@
"rootDir": "./src",
"outDir": "./dist",
"paths": {
"spine-core": [
"@esotericsoftware/spine-core": [
"../spine-core/src"
]
}

View File

@ -3,6 +3,10 @@
"version": "4.0.1",
"description": "The official Spine Runtimes for the web.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/**/*"
],
"scripts": {},
"repository": {
"type": "git",

View File

@ -0,0 +1,30 @@
{
"name": "@esotericsoftware/spine-player",
"version": "4.0.1",
"description": "The official Spine Runtimes for the web.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/**/*"
],
"scripts": {},
"repository": {
"type": "git",
"url": "git+https://github.com/esotericsoftware/spine-runtimes.git"
},
"keywords": [
"gamedev",
"animations",
"2d",
"spine",
"game-dev",
"runtimes",
"skeletal"
],
"author": "Esoteric Software LLC",
"license": "LicenseRef-LICENSE",
"bugs": {
"url": "https://github.com/esotericsoftware/spine-runtimes/issues"
},
"homepage": "https://github.com/esotericsoftware/spine-runtimes#readme"
}

View File

@ -27,8 +27,10 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
module spine {
export interface SpinePlayerConfig {
import { Animation, AnimationState, AnimationStateData, AtlasAttachmentLoader, Bone, Color, Downloader, MathUtils, MixBlend, MixDirection, Skeleton, SkeletonBinary, SkeletonData, SkeletonJson, StringMap, TextureAtlas, TextureFilter, TimeKeeper, TrackEntry, Vector2 } from "@esotericsoftware/spine-core"
import { AssetManager, GLTexture, Input, LoadingScreen, ManagedWebGLRenderingContext, ResizeMode, SceneRenderer, Vector3 } from "@esotericsoftware/spine-webgl"
export interface SpinePlayerConfig {
/* The URL of the skeleton JSON file (.json). */
jsonUrl: string
@ -44,7 +46,7 @@ module spine {
/* Raw data URIs, mapping a path to base64 encoded raw data. When player's asset manager resolves the jsonUrl, binaryUrl,
atlasUrl, 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 */
rawDataURIs: Map<string>
rawDataURIs: StringMap<string>
/* Optional: The name of the animation to be played. Default: empty animation */
animation: string
@ -105,7 +107,7 @@ module spine {
transitionTime: number
/* Optional: Viewports for specific animations. Default: none */
animations: Map<Viewport>
animations: StringMap<Viewport>
}
/* Optional: Whether the canvas is transparent, allowing the web page behind the canvas to show through when
@ -158,10 +160,10 @@ module spine {
/* Optional: The downloader used by the player's asset manager. Passing the same downloader to multiple players using the
same assets ensures the assets are only downloaded once. Default: new instance */
downloader: spine.Downloader
}
downloader: Downloader
}
export interface Viewport {
export interface Viewport {
/* Optional: The position and size of the viewport in the skeleton's world coordinates. Default: the bounding box that fits
the current animation */
x: number,
@ -174,16 +176,16 @@ module spine {
padRight: string | number
padTop: string | number
padBottom: string | number
}
}
export class SpinePlayer {
export class SpinePlayer {
public parent: HTMLElement;
public dom: HTMLElement;
public canvas: HTMLCanvasElement;
public context: spine.webgl.ManagedWebGLRenderingContext;
public sceneRenderer: spine.webgl.SceneRenderer;
public loadingScreen: spine.webgl.LoadingScreen;
public assetManager: spine.webgl.AssetManager;
public context: ManagedWebGLRenderingContext;
public sceneRenderer: SceneRenderer;
public loadingScreen: LoadingScreen;
public assetManager: AssetManager;
public bg = new Color();
public bgFullscreen = new Color();
@ -215,7 +217,7 @@ module spine {
private previousViewport: Viewport;
private viewportTransitionStart = 0;
constructor (parent: HTMLElement | string, private config: SpinePlayerConfig) {
constructor(parent: HTMLElement | string, private config: SpinePlayerConfig) {
this.parent = typeof parent === "string" ? document.getElementById(parent) : parent;
if (!this.parent) throw new Error("SpinePlayer parent not found: " + parent);
@ -252,8 +254,8 @@ module spine {
requestAnimationFrame(() => this.drawFrame());
}
private validateConfig (config: SpinePlayerConfig) {
if (!config) throw new Error("A configuration object must be passed to to new spine.SpinePlayer().");
private validateConfig(config: SpinePlayerConfig) {
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.jsonUrl && !config.binaryUrl) throw new Error("A URL must be specified for the skeleton JSON or binary file.");
if (!config.atlasUrl) throw new Error("A URL must be specified for the atlas file.");
@ -276,7 +278,7 @@ module spine {
if (config.defaultMix === void 0) config.defaultMix = 0.25;
}
private initialize (): HTMLElement {
private initialize(): HTMLElement {
let config = this.config;
let dom = this.dom;
@ -288,17 +290,17 @@ module spine {
try {
// Setup the OpenGL context.
this.canvas = findWithClass(dom, "spine-player-canvas") as HTMLCanvasElement;
this.context = new spine.webgl.ManagedWebGLRenderingContext(this.canvas, { alpha: config.alpha });
this.context = new ManagedWebGLRenderingContext(this.canvas, { alpha: config.alpha });
// Setup the scene renderer and loading screen.
this.sceneRenderer = new spine.webgl.SceneRenderer(this.canvas, this.context, true);
if (config.showLoading) this.loadingScreen = new spine.webgl.LoadingScreen(this.sceneRenderer);
this.sceneRenderer = new SceneRenderer(this.canvas, this.context, true);
if (config.showLoading) this.loadingScreen = new LoadingScreen(this.sceneRenderer);
} catch (e) {
this.showError("Sorry, your browser does not support WebGL.\nPlease use the latest version of Firefox, Chrome, Edge, or Safari.", e);
this.showError("Sorry, your browser does not support \nPlease use the latest version of Firefox, Chrome, Edge, or Safari.", e);
}
// Load the assets.
this.assetManager = new spine.webgl.AssetManager(this.context, "", config.downloader);
this.assetManager = new AssetManager(this.context, "", config.downloader);
if (config.rawDataURIs) {
for (let path in config.rawDataURIs)
this.assetManager.setRawDataURI(path, config.rawDataURIs[path]);
@ -389,7 +391,7 @@ module spine {
return dom;
}
private loadSkeleton () {
private loadSkeleton() {
if (this.error) return;
if (this.assetManager.hasErrors())
@ -415,7 +417,7 @@ module spine {
minFilter = TextureFilter.Linear; // Don't use mipmaps without anisotropic.
page.texture.setFilters(minFilter, TextureFilter.Nearest);
}
if (minFilter != TextureFilter.Nearest && minFilter != TextureFilter.Linear) (page.texture as spine.webgl.GLTexture).update(true);
if (minFilter != TextureFilter.Nearest && minFilter != TextureFilter.Linear) (page.texture as GLTexture).update(true);
}
// Load skeleton data.
@ -513,17 +515,17 @@ module spine {
}
}
private setupInput () {
private setupInput() {
let config = this.config;
let controlBones = config.controlBones;
if (!controlBones.length && !config.showControls) return;
let selectedBones = this.selectedBones = new Array<Bone>(controlBones.length);
let canvas = this.canvas;
let target: Bone = null;
let offset = new spine.Vector2();
let coords = new spine.webgl.Vector3();
let mouse = new spine.webgl.Vector3();
let position = new spine.Vector2();
let offset = new Vector2();
let coords = new Vector3();
let mouse = new Vector3();
let position = new Vector2();
let skeleton = this.skeleton;
let renderer = this.sceneRenderer;
@ -550,7 +552,7 @@ module spine {
return best;
};
new spine.webgl.Input(canvas).addListener({
new Input(canvas).addListener({
down: (x, y) => {
target = closest(x, y);
},
@ -619,7 +621,7 @@ module spine {
}
}
play () {
play() {
this.paused = false;
let config = this.config;
if (config.showControls) {
@ -640,7 +642,7 @@ module spine {
}
}
pause () {
pause() {
this.paused = true;
if (this.config.showControls) {
this.playerControls.classList.remove("spine-player-controls-hidden");
@ -651,19 +653,19 @@ module spine {
}
/* Sets a new animation and viewport on track 0. */
setAnimation (animation: string | Animation, loop: boolean = true): TrackEntry {
setAnimation(animation: string | Animation, loop: boolean = true): TrackEntry {
animation = this.setViewport(animation);
return this.animationState.setAnimationWith(0, animation, loop);
}
/* Adds a new animation and viewport on track 0. */
addAnimation (animation: string | Animation, loop: boolean = true, delay: number = 0): TrackEntry {
addAnimation(animation: string | Animation, loop: boolean = true, delay: number = 0): TrackEntry {
animation = this.setViewport(animation);
return this.animationState.addAnimationWith(0, animation, loop, delay);
}
/* Sets the viewport for the specified animation. */
setViewport (animation: string | Animation): Animation {
setViewport(animation: string | Animation): Animation {
if (typeof animation == "string") animation = this.skeleton.data.findAnimation(animation);
this.previousViewport = this.currentViewport;
@ -709,18 +711,18 @@ module spine {
return animation;
}
private percentageToWorldUnit (size: number, percentageOrAbsolute: string | number): number {
private percentageToWorldUnit(size: number, percentageOrAbsolute: string | number): number {
if (typeof percentageOrAbsolute === "string")
return size * parseFloat(percentageOrAbsolute.substr(0, percentageOrAbsolute.length - 1)) / 100;
return percentageOrAbsolute;
}
private calculateAnimationViewport (animation: Animation, viewport: Viewport) {
private calculateAnimationViewport(animation: Animation, viewport: Viewport) {
this.skeleton.setToSetupPose();
let steps = 100, stepTime = animation.duration ? animation.duration / steps : 0, time = 0;
let minX = 100000000, maxX = -100000000, minY = 100000000, maxY = -100000000;
let offset = new spine.Vector2(), size = new spine.Vector2();
let offset = new Vector2(), size = new Vector2();
for (let i = 0; i < steps; i++, time += stepTime) {
animation.apply(this.skeleton, time, time, false, null, 1, MixBlend.setup, MixDirection.mixIn);
@ -742,7 +744,7 @@ module spine {
viewport.height = maxY - minY;
}
private drawFrame (requestNextFrame = true) {
private drawFrame(requestNextFrame = true) {
try {
if (this.error) return;
if (requestNextFrame && !this.stopRequestAnimationFrame) requestAnimationFrame(() => this.drawFrame());
@ -762,7 +764,7 @@ module spine {
if (skeleton) {
// Resize the canvas.
let renderer = this.sceneRenderer;
renderer.resize(webgl.ResizeMode.Expand);
renderer.resize(ResizeMode.Expand);
let playDelta = this.paused ? 0 : delta * this.speed;
if (config.frame) config.frame(this, playDelta);
@ -882,15 +884,15 @@ module spine {
}
}
stopRendering () {
stopRendering() {
this.stopRequestAnimationFrame = true;
}
private hidePopup (id: string): boolean {
private hidePopup(id: string): boolean {
return this.popup && this.popup.hide(id);
}
private showSpeedDialog (speedButton: HTMLElement) {
private showSpeedDialog(speedButton: HTMLElement) {
let id = "speed";
if (this.hidePopup(id)) return;
@ -910,7 +912,7 @@ module spine {
popup.show();
}
private showAnimationsDialog (animationsButton: HTMLElement) {
private showAnimationsDialog(animationsButton: HTMLElement) {
let id = "animations";
if (this.hidePopup(id)) return;
if (!this.skeleton || !this.skeleton.data.animations.length) return;
@ -940,7 +942,7 @@ module spine {
popup.show();
}
private showSkinsDialog (skinButton: HTMLElement) {
private showSkinsDialog(skinButton: HTMLElement) {
let id = "skins";
if (this.hidePopup(id)) return;
if (!this.skeleton || !this.skeleton.data.animations.length) return;
@ -968,7 +970,7 @@ module spine {
popup.show();
}
private showSettingsDialog (settingsButton: HTMLElement) {
private showSettingsDialog(settingsButton: HTMLElement) {
let id = "settings";
if (this.hidePopup(id)) return;
if (!this.skeleton || !this.skeleton.data.animations.length) return;
@ -996,7 +998,7 @@ module spine {
popup.show();
}
private showError (message: string, error: Error = null) {
private showError(message: string, error: Error = null) {
if (this.error) {
if (error) throw error; // Don't lose error if showError throws, is caught, and showError is called again.
} else {
@ -1008,20 +1010,20 @@ module spine {
throw (error ? error : new Error(message));
}
}
}
}
class Popup {
class Popup {
public dom: HTMLElement;
private className: string;
constructor (private id: string, private button: HTMLElement, private player: SpinePlayer, parent: HTMLElement, htmlContent: string) {
constructor(private id: string, private button: HTMLElement, private player: SpinePlayer, parent: HTMLElement, htmlContent: string) {
this.dom = createElement(/*html*/`<div class="spine-player-popup spine-player-hidden"></div>`);
this.dom.innerHTML = htmlContent;
parent.appendChild(this.dom);
this.className = "spine-player-button-icon-" + id + "-selected";
}
hide (id: string): boolean {
hide(id: string): boolean {
this.dom.remove();
this.button.classList.remove(this.className);
if (this.id == id) {
@ -1030,7 +1032,7 @@ module spine {
}
}
show () {
show() {
this.player.popup = this;
this.button.classList.add(this.className);
this.dom.classList.remove("spine-player-hidden");
@ -1063,16 +1065,16 @@ module spine {
};
window.addEventListener("click", windowClickListener);
}
}
}
class Switch {
class Switch {
private switch: HTMLElement;
private enabled = false;
public change: (value: boolean) => void;
constructor (private text: string) { }
constructor(private text: string) { }
create (): HTMLElement {
create(): HTMLElement {
this.switch = createElement(/*html*/`
<div class="spine-player-switch">
<span class="spine-player-switch-text">${this.text}</span>
@ -1087,26 +1089,26 @@ module spine {
return this.switch;
}
setEnabled (enabled: boolean) {
setEnabled(enabled: boolean) {
if (enabled) this.switch.classList.add("active");
else this.switch.classList.remove("active");
this.enabled = enabled;
}
isEnabled (): boolean {
isEnabled(): boolean {
return this.enabled;
}
}
}
class Slider {
class Slider {
private slider: HTMLElement;
private value: HTMLElement;
private knob: HTMLElement;
public change: (percentage: number) => void;
constructor (public snaps = 0, public snapPercentage = 0.1, public big = false) { }
constructor(public snaps = 0, public snapPercentage = 0.1, public big = false) { }
create (): HTMLElement {
create(): HTMLElement {
this.slider = createElement(/*html*/`
<div class="spine-player-slider ${this.big ? "big" : ""}">
<div class="spine-player-slider-value"></div>
@ -1117,7 +1119,7 @@ module spine {
this.setValue(0);
let dragging = false;
new spine.webgl.Input(this.slider).addListener({
new Input(this.slider).addListener({
down: (x, y) => {
dragging = true;
this.value.classList.add("hovering");
@ -1138,7 +1140,7 @@ module spine {
return this.slider;
}
setValue (percentage: number): number {
setValue(percentage: number): number {
percentage = Math.max(0, Math.min(1, percentage));
if (this.snaps) {
let snap = 1 / this.snaps;
@ -1154,34 +1156,33 @@ module spine {
// this.knob.style.left = "" + (-8 + percentage * this.slider.clientWidth) + "px";
return percentage;
}
}
}
function findWithClass (element: HTMLElement, className: string): HTMLElement {
function findWithClass(element: HTMLElement, className: string): HTMLElement {
return element.getElementsByClassName(className)[0] as HTMLElement;
}
}
function createElement (html: string): HTMLElement {
function createElement(html: string): HTMLElement {
let div = document.createElement("div");
div.innerHTML = html;
return div.children[0] as HTMLElement;
}
}
function removeClass (elements: HTMLCollection, clazz: string) {
function removeClass(elements: HTMLCollection, clazz: string) {
for (let i = 0; i < elements.length; i++)
elements[i].classList.remove(clazz);
}
}
function toString (object: any) {
function toString(object: any) {
return JSON.stringify(object)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&#34;")
.replace(/'/g, "&#39;");
}
const BONE_INNER_OVER = new spine.Color(0.478, 0, 0, 0.25);
const BONE_OUTER_OVER = new spine.Color(1, 1, 1, 1);
const BONE_INNER = new spine.Color(0.478, 0, 0, 0.5);
const BONE_OUTER = new spine.Color(1, 0, 0, 0.8);
}
const BONE_INNER_OVER = new Color(0.478, 0, 0, 0.25);
const BONE_OUTER_OVER = new Color(1, 1, 1, 1);
const BONE_INNER = new Color(0.478, 0, 0, 0.5);
const BONE_OUTER = new Color(1, 0, 0, 0.8);

View File

@ -27,10 +27,9 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
declare function CodeMirror (el: Element, config: any): void;
declare function CodeMirror(el: Element, config: any): void;
module spine {
export class SpinePlayerEditor {
export class SpinePlayerEditor {
private static DEFAULT_CODE =
`
<script src="https://esotericsoftware.com/files/spine-player/4.0/spine-player.js"></script>
@ -58,11 +57,11 @@ body { margin: 0px; }
private code: any;
private player: HTMLIFrameElement;
constructor (parent: HTMLElement) {
constructor(parent: HTMLElement) {
this.render(parent);
}
private render (parent: HTMLElement) {
private render(parent: HTMLElement) {
let dom = /*html*/`
<div class="spine-player-editor-container">
<div class="spine-player-editor-code"></div>
@ -91,19 +90,19 @@ body { margin: 0px; }
})
}
setPreAndPostfix (prefix: string, postfix: string) {
setPreAndPostfix(prefix: string, postfix: string) {
this.prefix = prefix;
this.postfix = postfix;
this.startPlayer()
}
setCode (code: string) {
setCode(code: string) {
this.code.setValue(code);
this.startPlayer();
}
private timerId = 0;
startPlayer () {
startPlayer() {
clearTimeout(this.timerId);
this.timerId = setTimeout(() => {
let code = this.code.getDoc().getValue();
@ -113,5 +112,4 @@ body { margin: 0px; }
this.player.src = "data:text/html;base64," + code;
}, 500);
}
}
}

View File

@ -0,0 +1,27 @@
export * from './Player';
export * from './PlayerEditor';
export * from "@esotericsoftware/spine-core";
export * from "@esotericsoftware/spine-webgl";
// Before modularization, we would expose spine-core on the global
// `spine` object, and spine-webgl on the global `spine.webgl` object.
// This was used by clients when including spine-webgl via <script src="spine-webgl.js">
//
// Now with modularization and using esbuild for bundling, we need to emulate this old
// behaviour as to not break old clients.
//
// We pass `--global-name=spine` to esbuild. This will create an object containing
// all exports and assign it to the global variable called `spine`.
//
// That solves half the issue. We also need to assign the exports object to
// `spine.webgl`. esbuild creates a local variable called `scr_exports` pointing
// to the exports object. We get to it via eval, then assign it to itself, on a new
// property called `webgl`. The client can then access the APIs through `spine` and
// `spine.webgl` as before (with the caveat that both spine-core and spine-webgl are
// now in `spine` and `spine.webgl`).
//
// This will break if esbuild renames the variable `src_exports` pointing to
// the exports object.
let exports = eval("src_exports");
if (exports) exports.webgl = exports;

View File

@ -0,0 +1,30 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"baseUrl": ".",
"rootDir": "./src",
"outDir": "./dist",
"paths": {
"@esotericsoftware/spine-core": [
"../spine-core/src"
],
"@esotericsoftware/spine-webgl": [
"../spine-webgl/src"
]
}
},
"include": [
"**/*.ts"
],
"exclude": [
"dist/**/*.d.ts"
],
"references": [
{
"path": "../spine-core"
},
{
"path": "../spine-webgl"
}
]
}

View File

@ -3,6 +3,10 @@
"version": "4.0.1",
"description": "The official Spine Runtimes for the web.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/**/*"
],
"scripts": {},
"repository": {
"type": "git",

View File

@ -27,14 +27,15 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { AssetManagerBase, Downloader } from "spine-core";
import { AssetManagerBase, Downloader } from "@esotericsoftware/spine-core"
import { ManagedWebGLRenderingContext } from "./WebGL";
import { GLTexture } from "./GLTexture";
export class AssetManager extends AssetManagerBase {
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, pathPrefix: string = "", downloader: Downloader = null) {
super((image: HTMLImageElement | ImageBitmap) => {
return new spine.webgl.GLTexture(context, image);
return new GLTexture(context, image);
}, pathPrefix, downloader);
}
}

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Texture, Disposable, Restorable, TextureFilter, TextureWrap } from "spine-core";
import { Texture, Disposable, Restorable, TextureFilter, TextureWrap } from "@esotericsoftware/spine-core";
import { ManagedWebGLRenderingContext } from "./WebGL";
export class GLTexture extends Texture implements Disposable, Restorable {

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Pool } from "spine-core";
import { Pool } from "@esotericsoftware/spine-core";
export class Input {
element: HTMLElement;
@ -38,7 +38,7 @@ export class Input {
private listeners = new Array<InputListener>();
touchesPool = new Pool<Touch>(() => {
return new spine.webgl.Touch(0, 0, 0);
return new Touch(0, 0, 0);
});
constructor(element: HTMLElement) {

View File

@ -27,6 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Color, TimeKeeper } from "@esotericsoftware/spine-core";
import { GLTexture } from "./GLTexture";
import { ResizeMode, SceneRenderer } from "./SceneRenderer";
@ -44,9 +45,9 @@ export class LoadingScreen {
private angle = 0;
private fadeOut = 0;
private fadeIn = 0;
private timeKeeper = new spine.TimeKeeper();
backgroundColor = new spine.Color(0.135, 0.135, 0.135, 1);
private tempColor = new spine.Color();
private timeKeeper = new TimeKeeper();
backgroundColor = new Color(0.135, 0.135, 0.135, 1);
private tempColor = new Color();
constructor(renderer: SceneRenderer) {
this.renderer = renderer;

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Disposable, Restorable } from "spine-core";
import { Disposable, Restorable } from "@esotericsoftware/spine-core";
import { Shader } from "./Shader";
import { ManagedWebGLRenderingContext } from "./WebGL";

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Disposable } from "spine-core";
import { Disposable } from "@esotericsoftware/spine-core";
import { GLTexture } from "./GLTexture";
import { Mesh, Position2Attribute, ColorAttribute, TexCoordAttribute, Color2Attribute } from "./Mesh";
import { Shader } from "./Shader";

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Color, Disposable, Skeleton, MathUtils, TextureAtlasRegion } from "spine-core";
import { Color, Disposable, Skeleton, MathUtils, TextureAtlasRegion } from "@esotericsoftware/spine-core";
import { OrthoCamera } from "./Camera";
import { GLTexture } from "./GLTexture";
import { PolygonBatcher } from "./PolygonBatcher";

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Disposable, Restorable } from "spine-core";
import { Disposable, Restorable } from "@esotericsoftware/spine-core";
import { ManagedWebGLRenderingContext } from "./WebGL";
export class Shader implements Disposable, Restorable {

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Disposable, Color, Vector2, MathUtils } from "spine-core";
import { Disposable, Color, Vector2, MathUtils } from "@esotericsoftware/spine-core";
import { Mesh, Position2Attribute, ColorAttribute } from "./Mesh";
import { Shader } from "./Shader";
import { ManagedWebGLRenderingContext } from "./WebGL";

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Disposable, Color, SkeletonBounds, Utils, Skeleton, RegionAttachment, MeshAttachment, PathAttachment, ClippingAttachment } from "spine-core";
import { Disposable, Color, SkeletonBounds, Utils, Skeleton, RegionAttachment, MeshAttachment, PathAttachment, ClippingAttachment } from "@esotericsoftware/spine-core";
import { ShapeRenderer } from "./ShapeRenderer";
import { ManagedWebGLRenderingContext } from "./WebGL";

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { NumberArrayLike, VertexEffect, Color, SkeletonClipping, Vector2, Utils, Skeleton, BlendMode, RegionAttachment, TextureAtlasRegion, MeshAttachment, ClippingAttachment } from "spine-core";
import { NumberArrayLike, VertexEffect, Color, SkeletonClipping, Vector2, Utils, Skeleton, BlendMode, RegionAttachment, TextureAtlasRegion, MeshAttachment, ClippingAttachment } from "@esotericsoftware/spine-core";
import { GLTexture } from "./GLTexture";
import { PolygonBatcher } from "./PolygonBatcher";
import { ManagedWebGLRenderingContext, WebGLBlendModeConverter } from "./WebGL";
@ -120,7 +120,7 @@ export class SkeletonRenderer {
renderable.numVertices = (mesh.worldVerticesLength >> 1);
renderable.numFloats = renderable.numVertices * clippedVertexSize;
if (renderable.numFloats > renderable.vertices.length) {
renderable.vertices = this.vertices = spine.Utils.newFloatArray(renderable.numFloats);
renderable.vertices = this.vertices = Utils.newFloatArray(renderable.numFloats);
}
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
triangles = mesh.triangles;

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Restorable, BlendMode } from "spine-core";
import { Restorable, BlendMode } from "@esotericsoftware/spine-core";
export class ManagedWebGLRenderingContext {
public canvas: HTMLCanvasElement | OffscreenCanvas;

View File

@ -14,7 +14,7 @@ export * from './SkeletonRenderer';
export * from './Vector3';
export * from './WebGL';
export * from "spine-core";
export * from "@esotericsoftware/spine-core";
// Before modularization, we would expose spine-core on the global
// `spine` object, and spine-webgl on the global `spine.webgl` object.
@ -35,9 +35,5 @@ export * from "spine-core";
//
// This will break if esbuild renames the variable `src_exports` pointing to
// the exports object.
declare global {
var spine: any;
}
let exports = eval("src_exports");
exports.webgl = exports;
if (exports) exports.webgl = exports;

View File

@ -5,7 +5,7 @@
"rootDir": "./src",
"outDir": "./dist",
"paths": {
"spine-core": [
"@esotericsoftware/spine-core": [
"../spine-core/src"
]
}

View File

@ -10,7 +10,6 @@
"ES2015"
],
"declaration": true,
"declarationMap": true,
"composite": true,
"moduleResolution": "node",
}

View File

@ -6,6 +6,12 @@
},
{
"path": "./spine-canvas"
},
{
"path": "./spine-webgl"
},
{
"path": "./spine-player"
}
]
}