mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 09:46:02 +08:00
[ts] Modularize player, add package.json files, fix up module paths.
This commit is contained in:
parent
79f0abf765
commit
17c342ac61
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
30
spine-ts/package-lock.json
generated
30
spine-ts/package-lock.json
generated
@ -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"
|
||||
},
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
@ -5,7 +5,7 @@
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"paths": {
|
||||
"spine-core": [
|
||||
"@esotericsoftware/spine-core": [
|
||||
"../spine-core/src"
|
||||
]
|
||||
}
|
||||
|
||||
@ -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",
|
||||
|
||||
30
spine-ts/spine-player/package.json
Normal file
30
spine-ts/spine-player/package.json
Normal 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"
|
||||
}
|
||||
@ -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, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
spine-ts/spine-player/src/index.ts
Normal file
27
spine-ts/spine-player/src/index.ts
Normal 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;
|
||||
30
spine-ts/spine-player/tsconfig.json
Normal file
30
spine-ts/spine-player/tsconfig.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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",
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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";
|
||||
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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";
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -5,7 +5,7 @@
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"paths": {
|
||||
"spine-core": [
|
||||
"@esotericsoftware/spine-core": [
|
||||
"../spine-core/src"
|
||||
]
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
"ES2015"
|
||||
],
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"composite": true,
|
||||
"moduleResolution": "node",
|
||||
}
|
||||
|
||||
@ -6,6 +6,12 @@
|
||||
},
|
||||
{
|
||||
"path": "./spine-canvas"
|
||||
},
|
||||
{
|
||||
"path": "./spine-webgl"
|
||||
},
|
||||
{
|
||||
"path": "./spine-player"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user