浏览代码

Merge branch '3.7-beta' into 3.7-beta-cpp

badlogic 6 年之前
父节点
当前提交
b2b2845f88
共有 34 个文件被更改,包括 2414 次插入782 次删除
  1. 5 5
      spine-csharp/src/ExposedList.cs
  2. 1 1
      spine-csharp/src/PathConstraint.cs
  3. 6 0
      spine-csharp/src/Skin.cs
  4. 14 0
      spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java
  5. 2 1
      spine-sfml/cpp/example/main.cpp
  6. 125 47
      spine-ts/build/spine-all.d.ts
  7. 686 10
      spine-ts/build/spine-all.js
  8. 0 0
      spine-ts/build/spine-all.js.map
  9. 26 26
      spine-ts/build/spine-canvas.d.ts
  10. 7 3
      spine-ts/build/spine-canvas.js
  11. 0 0
      spine-ts/build/spine-canvas.js.map
  12. 21 21
      spine-ts/build/spine-core.d.ts
  13. 7 3
      spine-ts/build/spine-core.js
  14. 0 0
      spine-ts/build/spine-core.js.map
  15. 24 24
      spine-ts/build/spine-threejs.d.ts
  16. 7 3
      spine-ts/build/spine-threejs.js
  17. 0 0
      spine-ts/build/spine-threejs.js.map
  18. 34 34
      spine-ts/build/spine-webgl.d.ts
  19. 21 10
      spine-ts/build/spine-webgl.js
  20. 0 0
      spine-ts/build/spine-webgl.js.map
  21. 75 50
      spine-ts/build/spine-widget.d.ts
  22. 424 152
      spine-ts/build/spine-widget.js
  23. 0 0
      spine-ts/build/spine-widget.js.map
  24. 249 0
      spine-ts/widget/css/spine-player.css
  25. 8 125
      spine-ts/widget/example/player-test.html
  26. 562 211
      spine-ts/widget/src/Player.ts
  27. 1 2
      spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs
  28. 50 14
      spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs
  29. 13 6
      spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs
  30. 5 11
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs
  31. 9 4
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs
  32. 12 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs
  33. 5 0
      spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs
  34. 15 14
      spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs

+ 5 - 5
spine-csharp/src/ExposedList.cs

@@ -17,10 +17,10 @@
 // distribute, sublicense, and/or sell copies of the Software, and to
 // permit persons to whom the Software is furnished to do so, subject to
 // the following conditions:
-//
+// 
 // The above copyright notice and this permission notice shall be
 // included in all copies or substantial portions of the Software.
-//
+// 
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -82,8 +82,8 @@ namespace Spine {
 			version++;
 		}
 
-		public void GrowIfNeeded (int newCount) {
-			int minimumSize = Count + newCount;
+		public void GrowIfNeeded (int addedCount) {
+			int minimumSize = Count + addedCount;
 			if (minimumSize > Items.Length)
 				Capacity = Math.Max(Math.Max(Capacity * 2, DefaultCapacity), minimumSize);
 		}
@@ -466,7 +466,7 @@ namespace Spine {
 		public T Pop () {
 			if (Count == 0)
 				throw new InvalidOperationException("List is empty. Nothing to pop.");
-
+			
 			int i = Count - 1;
 			T item = Items[i];
 			Items[i] = default(T);

+ 1 - 1
spine-csharp/src/PathConstraint.cs

@@ -71,7 +71,7 @@ namespace Spine {
 		public void Apply () {
 			Update();
 		}
-
+			
 		public void Update () {
 			PathAttachment attachment = target.Attachment as PathAttachment;
 			if (attachment == null) return;

+ 6 - 0
spine-csharp/src/Skin.cs

@@ -63,6 +63,12 @@ namespace Spine {
 			return attachment;
 		}
 
+		/// <summary> Removes the attachment in the skin for the specified slot index and name, if any.</summary>
+		public void RemoveAttachment (int slotIndex, string name) {
+			if (slotIndex < 0) throw new ArgumentOutOfRangeException("slotIndex", "slotIndex must be >= 0");
+			attachments.Remove(new AttachmentKeyTuple(slotIndex, name));
+		}
+
 		/// <summary>Finds the skin keys for a given slot. The results are added to the passed List(names).</summary>
 		/// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
 		/// <param name="names">Found skin key names will be added to this list.</param>

+ 14 - 0
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java

@@ -34,6 +34,7 @@ import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.ObjectMap;
 import com.badlogic.gdx.utils.ObjectMap.Entry;
 import com.badlogic.gdx.utils.Pool;
+
 import com.esotericsoftware.spine.attachments.Attachment;
 
 /** Stores attachments by slot index and attachment name.
@@ -77,6 +78,15 @@ public class Skin {
 		return attachments.get(lookup);
 	}
 
+	/** Removes the attachment in the skin for the specified slot index and name, if any. */
+	public void removeAttachment (int slotIndex, String name) {
+		if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0.");
+		Key key = keyPool.obtain();
+		key.set(slotIndex, name);
+		attachments.remove(key);
+		keyPool.free(key);
+	}
+
 	public void findNamesForSlot (int slotIndex, Array<String> names) {
 		if (names == null) throw new IllegalArgumentException("names cannot be null.");
 		if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0.");
@@ -97,6 +107,10 @@ public class Skin {
 		attachments.clear(1024);
 	}
 
+	public int size () {
+		return attachments.size;
+	}
+
 	/** The skin's name, which is unique within the skeleton. */
 	public String getName () {
 		return name;

+ 2 - 1
spine-sfml/cpp/example/main.cpp

@@ -444,7 +444,7 @@ void test (SkeletonData* skeletonData, Atlas* atlas) {
 	Skeleton skeleton(skeletonData);
 	AnimationStateData animationStateData(skeletonData);
 	AnimationState animationState(&animationStateData);
-	animationState.setAnimation(0, "drive", true);
+	animationState.setAnimation(0, "idle", true);
 
 	float d = 3;
 	for (int i = 0; i < 1; i++) {
@@ -459,6 +459,7 @@ int main () {
 	DebugExtension dbgExtension(SpineExtension::getInstance());
 	SpineExtension::setInstance(&dbgExtension);
 
+	testcase(test, "data/yellow_god.json", "data/yellow_god.skel", "data/yellow_god.atlas", 0.6f);
 	testcase(spineboy, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy.atlas", 0.6f);
 	testcase(stretchymanStrechyIk, "data/stretchyman-stretchy-ik.json", "data/stretchyman-stretchy-ik.skel", "data/stretchyman.atlas", 0.6f);
 	testcase(spineboy, "data/spineboy-ess.json", "data/spineboy-ess.skel", "data/spineboy.atlas", 0.6f);

+ 125 - 47
spine-ts/build/spine-all.d.ts

@@ -16,11 +16,11 @@ declare module spine {
 		setup = 0,
 		first = 1,
 		replace = 2,
-		add = 3,
+		add = 3
 	}
 	enum MixDirection {
 		in = 0,
-		out = 1,
+		out = 1
 	}
 	enum TimelineType {
 		rotate = 0,
@@ -37,7 +37,7 @@ declare module spine {
 		pathConstraintPosition = 11,
 		pathConstraintSpacing = 12,
 		pathConstraintMix = 13,
-		twoColor = 14,
+		twoColor = 14
 	}
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
@@ -341,7 +341,7 @@ declare module spine {
 		end = 2,
 		dispose = 3,
 		complete = 4,
-		event = 5,
+		event = 5
 	}
 	interface AnimationStateListener2 {
 		start(entry: TrackEntry): void;
@@ -380,8 +380,8 @@ declare module spine {
 		private toLoad;
 		private loaded;
 		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		private static downloadText(url, success, error);
-		private static downloadBinary(url, success, error);
+		private static downloadText;
+		private static downloadBinary;
 		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
 		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
 		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
@@ -414,7 +414,7 @@ declare module spine {
 		Normal = 0,
 		Additive = 1,
 		Multiply = 2,
-		Screen = 3,
+		Screen = 3
 	}
 }
 declare module spine {
@@ -483,7 +483,7 @@ declare module spine {
 		OnlyTranslation = 1,
 		NoRotationOrReflection = 2,
 		NoScale = 3,
-		NoScaleOrReflection = 4,
+		NoScaleOrReflection = 4
 	}
 }
 declare module spine {
@@ -593,17 +593,17 @@ declare module spine {
 	}
 	enum PositionMode {
 		Fixed = 0,
-		Percent = 1,
+		Percent = 1
 	}
 	enum SpacingMode {
 		Length = 0,
 		Fixed = 1,
-		Percent = 2,
+		Percent = 2
 	}
 	enum RotateMode {
 		Tangent = 0,
 		Chain = 1,
-		ChainScale = 2,
+		ChainScale = 2
 	}
 }
 declare module spine {
@@ -614,12 +614,12 @@ declare module spine {
 		private rawAssets;
 		private errors;
 		constructor(pathPrefix?: string);
-		private queueAsset(clientId, textureLoader, path);
+		private queueAsset;
 		loadText(clientId: string, path: string): void;
 		loadJson(clientId: string, path: string): void;
 		loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
 		get(clientId: string, path: string): any;
-		private updateClientAssets(clientAssets);
+		private updateClientAssets;
 		isLoadingComplete(clientId: string): boolean;
 		dispose(): void;
 		hasErrors(): boolean;
@@ -670,7 +670,7 @@ declare module spine {
 		findIkConstraint(constraintName: string): IkConstraint;
 		findTransformConstraint(constraintName: string): TransformConstraint;
 		findPathConstraint(constraintName: string): PathConstraint;
-		getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
+		getBounds(offset: Vector2, size: Vector2, temp?: Array<number>): void;
 		update(delta: number): void;
 	}
 }
@@ -823,12 +823,12 @@ declare module spine {
 		MipMapNearestNearest = 9984,
 		MipMapLinearNearest = 9985,
 		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987,
+		MipMapLinearLinear = 9987
 	}
 	enum TextureWrap {
 		MirroredRepeat = 33648,
 		ClampToEdge = 33071,
-		Repeat = 10497,
+		Repeat = 10497
 	}
 	class TextureRegion {
 		renderObject: any;
@@ -855,7 +855,7 @@ declare module spine {
 		pages: TextureAtlasPage[];
 		regions: TextureAtlasRegion[];
 		constructor(atlasText: string, textureLoader: (path: string) => any);
-		private load(atlasText, textureLoader);
+		private load;
 		findRegion(name: string): TextureAtlasRegion;
 		dispose(): void;
 	}
@@ -931,9 +931,9 @@ declare module spine {
 		private polygonIndicesPool;
 		triangulate(verticesArray: ArrayLike<number>): Array<number>;
 		decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
-		private static isConcave(index, vertexCount, vertices, indices);
-		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
-		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static isConcave;
+		private static positiveArea;
+		private static winding;
 	}
 }
 declare module spine {
@@ -1105,7 +1105,7 @@ declare module spine {
 		Mesh = 2,
 		LinkedMesh = 3,
 		Path = 4,
-		Point = 5,
+		Point = 5
 	}
 }
 declare module spine {
@@ -1271,11 +1271,11 @@ declare module spine.canvas {
 		private tempColor;
 		constructor(context: CanvasRenderingContext2D);
 		draw(skeleton: Skeleton): void;
-		private drawImages(skeleton);
-		private drawTriangles(skeleton);
-		private drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
-		private computeRegionVertices(slot, region, pma);
-		private computeMeshVertices(slot, mesh, pma);
+		private drawImages;
+		private drawTriangles;
+		private drawTriangle;
+		private computeRegionVertices;
+		private computeMeshVertices;
 	}
 }
 declare module spine.webgl {
@@ -1330,7 +1330,7 @@ declare module spine.webgl {
 		touchesPool: Pool<Touch>;
 		private listeners;
 		constructor(element: HTMLElement);
-		private setupCallbacks(element);
+		private setupCallbacks;
 		addListener(listener: InputListener): void;
 		removeListener(listener: InputListener): void;
 	}
@@ -1439,7 +1439,7 @@ declare module spine.webgl {
 		drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
 		bind(shader: Shader): void;
 		unbind(shader: Shader): void;
-		private update();
+		private update;
 		restore(): void;
 		dispose(): void;
 	}
@@ -1465,7 +1465,7 @@ declare module spine.webgl {
 		constructor();
 	}
 	enum VertexAttributeType {
-		Float = 0,
+		Float = 0
 	}
 }
 declare module spine.webgl {
@@ -1484,7 +1484,7 @@ declare module spine.webgl {
 		begin(shader: Shader): void;
 		setBlendMode(srcBlend: number, dstBlend: number): void;
 		draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
-		private flush();
+		private flush;
 		end(): void;
 		getDrawCalls(): number;
 		dispose(): void;
@@ -1524,13 +1524,13 @@ declare module spine.webgl {
 		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
 		end(): void;
 		resize(resizeMode: ResizeMode): void;
-		private enableRenderer(renderer);
+		private enableRenderer;
 		dispose(): void;
 	}
 	enum ResizeMode {
 		Stretch = 0,
 		Expand = 1,
-		Fit = 2,
+		Fit = 2
 	}
 }
 declare module spine.webgl {
@@ -1558,9 +1558,9 @@ declare module spine.webgl {
 		getVertexShaderSource(): string;
 		getFragmentSource(): string;
 		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, vertexShader: string, fragmentShader: string);
-		private compile();
-		private compileShader(type, source);
-		private compileProgram(vs, fs);
+		private compile;
+		private compileShader;
+		private compileProgram;
 		restore(): void;
 		bind(): void;
 		unbind(): void;
@@ -1607,16 +1607,16 @@ declare module spine.webgl {
 		polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
 		circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
 		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
-		private vertex(x, y, color);
+		private vertex;
 		end(): void;
-		private flush();
-		private check(shapeType, numVertices);
+		private flush;
+		private check;
 		dispose(): void;
 	}
 	enum ShapeType {
 		Point = 0,
 		Line = 1,
-		Filled = 4,
+		Filled = 4
 	}
 }
 declare module spine.webgl {
@@ -1756,9 +1756,9 @@ declare module spine.threejs {
 		private tempColor;
 		constructor(skeletonData: SkeletonData);
 		update(deltaTime: number): void;
-		private clearBatches();
-		private nextBatch();
-		private updateGeometry();
+		private clearBatches;
+		private nextBatch;
+		private updateGeometry;
 	}
 }
 declare module spine.threejs {
@@ -1772,6 +1772,84 @@ declare module spine.threejs {
 		static toThreeJsTextureWrap(wrap: TextureWrap): THREE.Wrapping;
 	}
 }
+declare module spine {
+	interface SpinePlayerConfig {
+		jsonUrl: string;
+		atlasUrl: string;
+		animation: string;
+		animations: string[];
+		skin: string;
+		skins: string[];
+		controlBones: string[];
+		premultipliedAlpha: boolean;
+		showControls: boolean;
+		debug: {
+			bones: boolean;
+			regions: boolean;
+			meshes: boolean;
+			bounds: boolean;
+			paths: boolean;
+			clipping: boolean;
+			points: boolean;
+			hulls: boolean;
+		};
+		viewport: {
+			x: number;
+			y: number;
+			width: number;
+			height: number;
+		};
+		alpha: boolean;
+		backgroundColor: string;
+		backgroundImage: {
+			url: string;
+			x: number;
+			y: number;
+			width: number;
+			height: number;
+		};
+		success: (widget: SpineWidget) => void;
+		error: (widget: SpineWidget, msg: string) => void;
+	}
+	class SpinePlayer {
+		private config;
+		static HOVER_COLOR_INNER: Color;
+		static HOVER_COLOR_OUTER: Color;
+		static NON_HOVER_COLOR_INNER: Color;
+		static NON_HOVER_COLOR_OUTER: Color;
+		private sceneRenderer;
+		private dom;
+		private playerControls;
+		private canvas;
+		private timelineSlider;
+		private playButton;
+		private context;
+		private loadingScreen;
+		private assetManager;
+		private loaded;
+		private skeleton;
+		private animationState;
+		private time;
+		private paused;
+		private playTime;
+		private speed;
+		private selectedBones;
+		constructor(parent: HTMLElement, config: SpinePlayerConfig);
+		validateConfig(config: SpinePlayerConfig): SpinePlayerConfig;
+		showError(error: string): void;
+		render(): HTMLElement;
+		showSpeedDialog(): void;
+		showAnimationsDialog(): void;
+		showSkinsDialog(): void;
+		showSettingsDialog(): void;
+		drawFrame(requestNextFrame?: boolean): void;
+		scale(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): Vector2;
+		loadSkeleton(): void;
+		setupInput(): void;
+		private play;
+		private pause;
+	}
+}
 declare module spine {
 	class SpineWidget {
 		skeleton: Skeleton;
@@ -1793,10 +1871,10 @@ declare module spine {
 		private loaded;
 		private bounds;
 		constructor(element: HTMLElement | string, config: SpineWidgetConfig);
-		private validateConfig(config);
-		private load();
-		private render();
-		private resize();
+		private validateConfig;
+		private load;
+		private render;
+		private resize;
 		pause(): void;
 		play(): void;
 		isPlaying(): boolean;
@@ -1804,7 +1882,7 @@ declare module spine {
 		static loadWidgets(): void;
 		static loadWidget(widget: HTMLElement): void;
 		static pageLoaded: boolean;
-		private static ready();
+		private static ready;
 		static setupDOMListener(): void;
 	}
 	class SpineWidgetConfig {

+ 686 - 10
spine-ts/build/spine-all.js

@@ -1,7 +1,10 @@
 var __extends = (this && this.__extends) || (function () {
-	var extendStatics = Object.setPrototypeOf ||
-		({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-		function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+	var extendStatics = function (d, b) {
+		extendStatics = Object.setPrototypeOf ||
+			({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+			function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+		return extendStatics(d, b);
+	}
 	return function (d, b) {
 		extendStatics(d, b);
 		function __() { this.constructor = d; }
@@ -3826,6 +3829,7 @@ var spine;
 			return null;
 		};
 		Skeleton.prototype.getBounds = function (offset, size, temp) {
+			if (temp === void 0) { temp = new Array(2); }
 			if (offset == null)
 				throw new Error("offset cannot be null.");
 			if (size == null)
@@ -7226,7 +7230,7 @@ var spine;
 			}
 			Input.prototype.setupCallbacks = function (element) {
 				var _this = this;
-				element.addEventListener("mousedown", function (ev) {
+				var mouseDown = function (ev) {
 					if (ev instanceof MouseEvent) {
 						var rect = element.getBoundingClientRect();
 						var x = ev.clientX - rect.left;
@@ -7238,9 +7242,11 @@ var spine;
 						_this.lastX = x;
 						_this.lastY = y;
 						_this.buttonDown = true;
+						document.addEventListener("mousemove", mouseMove);
+						document.addEventListener("mouseup", mouseUp);
 					}
-				}, true);
-				element.addEventListener("mousemove", function (ev) {
+				};
+				var mouseMove = function (ev) {
 					if (ev instanceof MouseEvent) {
 						var rect = element.getBoundingClientRect();
 						var x = ev.clientX - rect.left;
@@ -7257,8 +7263,8 @@ var spine;
 						_this.lastX = x;
 						_this.lastY = y;
 					}
-				}, true);
-				element.addEventListener("mouseup", function (ev) {
+				};
+				var mouseUp = function (ev) {
 					if (ev instanceof MouseEvent) {
 						var rect = element.getBoundingClientRect();
 						var x = ev.clientX - rect.left;
@@ -7270,8 +7276,13 @@ var spine;
 						_this.lastX = x;
 						_this.lastY = y;
 						_this.buttonDown = false;
+						document.removeEventListener("mousemove", mouseMove);
+						document.removeEventListener("mouseup", mouseUp);
 					}
-				}, true);
+				};
+				element.addEventListener("mousedown", mouseDown, true);
+				element.addEventListener("mousemove", mouseMove, true);
+				element.addEventListener("mouseup", mouseUp, true);
 				element.addEventListener("touchstart", function (ev) {
 					if (_this.currTouch != null)
 						return;
@@ -7433,11 +7444,11 @@ var spine;
 				var renderer = this.renderer;
 				var canvas = renderer.canvas;
 				var gl = renderer.context.gl;
+				renderer.resize(webgl.ResizeMode.Stretch);
 				var oldX = renderer.camera.position.x, oldY = renderer.camera.position.y;
 				renderer.camera.position.set(canvas.width / 2, canvas.height / 2, 0);
 				renderer.camera.viewportWidth = canvas.width;
 				renderer.camera.viewportHeight = canvas.height;
-				renderer.resize(webgl.ResizeMode.Stretch);
 				if (!complete) {
 					gl.clearColor(this.backgroundColor.r, this.backgroundColor.g, this.backgroundColor.b, this.backgroundColor.a);
 					gl.clear(gl.COLOR_BUFFER_BIT);
@@ -10055,6 +10066,671 @@ var spine;
 	})(threejs = spine.threejs || (spine.threejs = {}));
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var Popup = (function () {
+		function Popup(parent, htmlContent) {
+			this.dom = createElement("\n\t\t\t\t<div class=\"spine-player-popup spine-player-hidden\">\n\t\t\t\t</div>\n\t\t\t");
+			this.dom.innerHTML = htmlContent;
+			parent.appendChild(this.dom);
+		}
+		Popup.prototype.show = function () {
+			var _this = this;
+			this.dom.classList.remove("spine-player-hidden");
+			var justClicked = true;
+			var windowClickListener = function (event) {
+				if (justClicked) {
+					justClicked = false;
+					return;
+				}
+				if (!isContained(_this.dom, event.target)) {
+					_this.dom.parentNode.removeChild(_this.dom);
+					window.removeEventListener("click", windowClickListener);
+				}
+			};
+			window.addEventListener("click", windowClickListener);
+		};
+		return Popup;
+	}());
+	var Switch = (function () {
+		function Switch(text) {
+			this.text = text;
+			this.enabled = false;
+		}
+		Switch.prototype.render = function () {
+			var _this = this;
+			this["switch"] = createElement("\n\t\t\t\t<div class=\"spine-player-switch\">\n\t\t\t\t\t<span class=\"spine-player-switch-text\">" + this.text + "</span>\n\t\t\t\t\t<div class=\"spine-player-switch-knob-area\">\n\t\t\t\t\t\t<div class=\"spine-player-switch-knob\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t");
+			this["switch"].addEventListener("click", function () {
+				_this.setEnabled(!_this.enabled);
+				if (_this.change)
+					_this.change(_this.enabled);
+			});
+			return this["switch"];
+		};
+		Switch.prototype.setEnabled = function (enabled) {
+			if (enabled)
+				this["switch"].classList.add("active");
+			else
+				this["switch"].classList.remove("active");
+			this.enabled = enabled;
+		};
+		Switch.prototype.isEnabled = function () {
+			return this.enabled;
+		};
+		return Switch;
+	}());
+	var Slider = (function () {
+		function Slider() {
+		}
+		Slider.prototype.render = function () {
+			var _this = this;
+			this.slider = createElement("\n\t\t\t\t<div class=\"spine-player-slider\">\n\t\t\t\t\t<div class=\"spine-player-slider-value\"></div>\n\t\t\t\t</div>\n\t\t\t");
+			this.value = findWithClass(this.slider, "spine-player-slider-value")[0];
+			this.setValue(0);
+			var input = new spine.webgl.Input(this.slider);
+			var dragging = false;
+			input.addListener({
+				down: function (x, y) {
+					dragging = true;
+				},
+				up: function (x, y) {
+					dragging = false;
+					var percentage = x / _this.slider.clientWidth;
+					percentage = Math.max(0, Math.min(percentage, 1));
+					_this.setValue(x / _this.slider.clientWidth);
+					if (_this.change)
+						_this.change(percentage);
+				},
+				moved: function (x, y) {
+					if (dragging) {
+						var percentage = x / _this.slider.clientWidth;
+						percentage = Math.max(0, Math.min(percentage, 1));
+						_this.setValue(x / _this.slider.clientWidth);
+						if (_this.change)
+							_this.change(percentage);
+					}
+				},
+				dragged: function (x, y) {
+					var percentage = x / _this.slider.clientWidth;
+					percentage = Math.max(0, Math.min(percentage, 1));
+					_this.setValue(x / _this.slider.clientWidth);
+					if (_this.change)
+						_this.change(percentage);
+				}
+			});
+			return this.slider;
+		};
+		Slider.prototype.setValue = function (percentage) {
+			percentage = Math.max(0, Math.min(1, percentage));
+			this.value.style.width = "" + (percentage * 100) + "%";
+		};
+		return Slider;
+	}());
+	var SpinePlayer = (function () {
+		function SpinePlayer(parent, config) {
+			this.config = config;
+			this.time = new spine.TimeKeeper();
+			this.paused = true;
+			this.playTime = 0;
+			this.speed = 1;
+			parent.appendChild(this.render());
+		}
+		SpinePlayer.prototype.validateConfig = function (config) {
+			if (!config)
+				throw new Error("Please pass a configuration to new.spine.SpinePlayer().");
+			if (!config.jsonUrl)
+				throw new Error("Please specify the URL of the skeleton JSON file.");
+			if (!config.atlasUrl)
+				throw new Error("Please specify the URL of the atlas file.");
+			if (!config.alpha)
+				config.alpha = false;
+			if (!config.backgroundColor)
+				config.backgroundColor = "#000000";
+			if (!config.premultipliedAlpha)
+				config.premultipliedAlpha = false;
+			if (!config.success)
+				config.success = function (widget) { };
+			if (!config.error)
+				config.error = function (widget, msg) { };
+			if (!config.debug)
+				config.debug = {
+					bones: false,
+					regions: false,
+					meshes: false,
+					bounds: false,
+					clipping: false,
+					paths: false,
+					points: false,
+					hulls: false
+				};
+			if (!config.debug.bones)
+				config.debug.bones = false;
+			if (!config.debug.bounds)
+				config.debug.bounds = false;
+			if (!config.debug.clipping)
+				config.debug.clipping = false;
+			if (!config.debug.hulls)
+				config.debug.hulls = false;
+			if (!config.debug.paths)
+				config.debug.paths = false;
+			if (!config.debug.points)
+				config.debug.points = false;
+			if (!config.debug.regions)
+				config.debug.regions = false;
+			if (!config.debug.meshes)
+				config.debug.meshes = false;
+			if (config.animations && config.animation) {
+				if (config.animations.indexOf(config.animation) < 0)
+					throw new Error("Default animation '" + config.animation + "' is not contained in the list of selectable animations " + escapeHtml(JSON.stringify(this.config.animations)) + ".");
+			}
+			if (config.skins && config.skin) {
+				if (config.skins.indexOf(config.skin) < 0)
+					throw new Error("Default skin '" + config.skin + "' is not contained in the list of selectable skins " + escapeHtml(JSON.stringify(this.config.skins)) + ".");
+			}
+			if (!config.controlBones)
+				config.controlBones = [];
+			if (!config.showControls)
+				config.showControls = true;
+			return config;
+		};
+		SpinePlayer.prototype.showError = function (error) {
+			var errorDom = findWithClass(this.dom, "spine-player-error")[0];
+			errorDom.classList.remove("spine-player-hidden");
+			errorDom.innerHTML = "<p style=\"text-align: center; align-self: center;\">" + error + "</p>";
+		};
+		SpinePlayer.prototype.render = function () {
+			var _this = this;
+			var config = this.config;
+			var dom = this.dom = createElement("\n\t\t\t\t<div class=\"spine-player\">\n\t\t\t\t\t<canvas class=\"spine-player-canvas\"></canvas>\n\t\t\t\t\t<div class=\"spine-player-error spine-player-hidden\"></div>\n\t\t\t\t\t<div class=\"spine-player-controls spine-player-popup-parent\">\n\t\t\t\t\t\t<div class=\"spine-player-timeline\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"spine-player-buttons\">\n\t\t\t\t\t\t\t<button id=\"spine-player-button-play-pause\" class=\"spine-player-button spine-player-button-icon-pause\"></button>\n\t\t\t\t\t\t\t<div class=\"spine-player-button-spacer\"></div>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-speed\" class=\"spine-player-button spine-player-button-icon-speed\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-animation\" class=\"spine-player-button spine-player-button-icon-animations\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-skin\" class=\"spine-player-button spine-player-button-icon-skins\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-settings\" class=\"spine-player-button spine-player-button-icon-settings\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-fullscreen\" class=\"spine-player-button spine-player-button-icon-fullscreen\"></button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t");
+			try {
+				this.config = this.validateConfig(config);
+			}
+			catch (e) {
+				this.showError(e);
+				return dom;
+			}
+			try {
+				this.canvas = findWithClass(dom, "spine-player-canvas")[0];
+				var webglConfig = { alpha: config.alpha };
+				this.context = new spine.webgl.ManagedWebGLRenderingContext(this.canvas, webglConfig);
+				this.sceneRenderer = new spine.webgl.SceneRenderer(this.canvas, this.context, true);
+				this.loadingScreen = new spine.webgl.LoadingScreen(this.sceneRenderer);
+			}
+			catch (e) {
+				this.showError("Sorry, your browser does not support WebGL.<br><br>Please use the latest version of Firefox, Chrome, Edge, or Safari.");
+				return dom;
+			}
+			this.assetManager = new spine.webgl.AssetManager(this.context);
+			this.assetManager.loadText(config.jsonUrl);
+			this.assetManager.loadTextureAtlas(config.atlasUrl);
+			if (config.backgroundImage && config.backgroundImage.url)
+				this.assetManager.loadTexture(config.backgroundImage.url);
+			requestAnimationFrame(function () { return _this.drawFrame(); });
+			this.playerControls = findWithClass(dom, "spine-player-controls")[0];
+			var timeline = findWithClass(dom, "spine-player-timeline")[0];
+			this.timelineSlider = new Slider();
+			timeline.appendChild(this.timelineSlider.render());
+			this.playButton = findWithId(dom, "spine-player-button-play-pause")[0];
+			var speedButton = findWithId(dom, "spine-player-button-speed")[0];
+			var animationButton = findWithId(dom, "spine-player-button-animation")[0];
+			var skinButton = findWithId(dom, "spine-player-button-skin")[0];
+			var settingsButton = findWithId(dom, "spine-player-button-settings")[0];
+			var fullscreenButton = findWithId(dom, "spine-player-button-fullscreen")[0];
+			this.playButton.onclick = function () {
+				if (_this.paused)
+					_this.play();
+				else
+					_this.pause();
+			};
+			speedButton.onclick = function () {
+				_this.showSpeedDialog();
+			};
+			animationButton.onclick = function () {
+				_this.showAnimationsDialog();
+			};
+			skinButton.onclick = function () {
+				_this.showSkinsDialog();
+			};
+			settingsButton.onclick = function () {
+				_this.showSettingsDialog();
+			};
+			fullscreenButton.onclick = function () {
+				var doc = document;
+				if (doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement) {
+					if (doc.exitFullscreen)
+						doc.exitFullscreen();
+					else if (doc.mozCancelFullScreen)
+						doc.mozCancelFullScreen();
+					else if (doc.webkitExitFullscreen)
+						doc.webkitExitFullscreen();
+					else if (doc.msExitFullscreen)
+						doc.msExitFullscreen();
+				}
+				else {
+					var player = dom;
+					if (player.requestFullscreen)
+						player.requestFullscreen();
+					else if (player.webkitRequestFullScreen)
+						player.webkitRequestFullScreen();
+					else if (player.mozRequestFullScreen)
+						player.mozRequestFullScreen();
+					else if (player.msRequestFullscreen)
+						player.msRequestFullscreen();
+				}
+			};
+			window.onresize = function () {
+				_this.drawFrame(false);
+			};
+			if (!config.showControls)
+				findWithClass(dom, "spine-player-controls ")[0].classList.add("spine-player-hidden");
+			return dom;
+		};
+		SpinePlayer.prototype.showSpeedDialog = function () {
+			var _this = this;
+			var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-row\" style=\"user-select: none; align-items: center; padding: 8px;\">\n\t\t\t\t\t<div style=\"margin-right: 16px;\">Speed</div>\n\t\t\t\t\t<div class=\"spine-player-column\">\n\t\t\t\t\t\t<div class=\"spine-player-speed-slider\" style=\"margin-bottom: 4px;\"></div>\n\t\t\t\t\t\t<div class=\"spine-player-row\" style=\"justify-content: space-between;\">\n\t\t\t\t\t\t\t<div>0.1x</div>\n\t\t\t\t\t\t\t<div>1x</div>\n\t\t\t\t\t\t\t<div>2x</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t");
+			var sliderParent = findWithClass(popup.dom, "spine-player-speed-slider")[0];
+			var slider = new Slider();
+			sliderParent.appendChild(slider.render());
+			slider.setValue(this.speed / 2);
+			slider.change = function (percentage) {
+				_this.speed = percentage * 2;
+			};
+			popup.show();
+		};
+		SpinePlayer.prototype.showAnimationsDialog = function () {
+			var _this = this;
+			if (!this.skeleton || this.skeleton.data.animations.length == 0)
+				return;
+			var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-popup-title\">Animations</div>\n\t\t\t\t<hr>\n\t\t\t\t<ul class=\"spine-player-list\"></ul>\n\t\t\t");
+			var rows = findWithClass(popup.dom, "spine-player-list")[0];
+			this.skeleton.data.animations.forEach(function (animation) {
+				if (_this.config.animations && _this.config.animations.indexOf(animation.name) < 0) {
+					return;
+				}
+				var row = createElement("\n\t\t\t\t\t<li class=\"spine-player-list-item selectable\">\n\t\t\t\t\t\t<div class=\"selectable-circle\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"selectable-text\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t");
+				if (animation.name == _this.config.animation)
+					row.classList.add("selected");
+				findWithClass(row, "selectable-text")[0].innerText = animation.name;
+				rows.appendChild(row);
+				row.onclick = function () {
+					removeClass(rows.children, "selected");
+					row.classList.add("selected");
+					_this.config.animation = animation.name;
+					_this.playTime = 0;
+					_this.animationState.setAnimation(0, _this.config.animation, true);
+				};
+			});
+			popup.show();
+		};
+		SpinePlayer.prototype.showSkinsDialog = function () {
+			var _this = this;
+			if (!this.skeleton || this.skeleton.data.animations.length == 0)
+				return;
+			var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-popup-title\">Skins</div>\n\t\t\t\t<hr>\n\t\t\t\t<ul class=\"spine-player-list\"></ul>\n\t\t\t");
+			var rows = findWithClass(popup.dom, "spine-player-list")[0];
+			this.skeleton.data.skins.forEach(function (skin) {
+				if (_this.config.skins && _this.config.skins.indexOf(skin.name) < 0) {
+					return;
+				}
+				var row = createElement("\n\t\t\t\t\t<li class=\"spine-player-list-item selectable\">\n\t\t\t\t\t\t<div class=\"selectable-circle\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"selectable-text\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t");
+				if (skin.name == _this.config.skin)
+					row.classList.add("selected");
+				findWithClass(row, "selectable-text")[0].innerText = skin.name;
+				rows.appendChild(row);
+				row.onclick = function () {
+					removeClass(rows.children, "selected");
+					row.classList.add("selected");
+					_this.config.skin = skin.name;
+					_this.skeleton.setSkinByName(_this.config.skin);
+					_this.skeleton.setSlotsToSetupPose();
+				};
+			});
+			popup.show();
+		};
+		SpinePlayer.prototype.showSettingsDialog = function () {
+			var _this = this;
+			if (!this.skeleton || this.skeleton.data.animations.length == 0)
+				return;
+			var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-popup-title\">Debug</div>\n\t\t\t\t<hr>\n\t\t\t\t<ul class=\"spine-player-list\">\n\t\t\t\t</li>\n\t\t\t");
+			var rows = findWithClass(popup.dom, "spine-player-list")[0];
+			var makeItem = function (label, name) {
+				var row = createElement("<li class=\"spine-player-list-item\"></li>");
+				var s = new Switch(label);
+				row.appendChild(s.render());
+				s.setEnabled(_this.config.debug[name]);
+				s.change = function (value) {
+					_this.config.debug[name] = value;
+				};
+				rows.appendChild(row);
+			};
+			makeItem("Show bones", "bones");
+			makeItem("Show regions", "regions");
+			makeItem("Show meshes", "meshes");
+			makeItem("Show bounds", "bounds");
+			makeItem("Show paths", "paths");
+			makeItem("Show clipping", "clipping");
+			makeItem("Show points", "points");
+			makeItem("Show hulls", "hulls");
+			popup.show();
+		};
+		SpinePlayer.prototype.drawFrame = function (requestNextFrame) {
+			var _this = this;
+			if (requestNextFrame === void 0) { requestNextFrame = true; }
+			if (requestNextFrame)
+				requestAnimationFrame(function () { return _this.drawFrame(); });
+			var ctx = this.context;
+			var gl = ctx.gl;
+			var bg = new spine.Color().setFromString(this.config.backgroundColor);
+			gl.clearColor(bg.r, bg.g, bg.b, bg.a);
+			gl.clear(gl.COLOR_BUFFER_BIT);
+			this.loadingScreen.draw(this.assetManager.isLoadingComplete());
+			if (this.assetManager.isLoadingComplete() && this.skeleton == null)
+				this.loadSkeleton();
+			this.sceneRenderer.resize(spine.webgl.ResizeMode.Expand);
+			if (this.loaded) {
+				if (!this.paused && this.config.animation) {
+					this.time.update();
+					var delta = this.time.delta * this.speed;
+					var animationDuration = this.animationState.getCurrent(0).animation.duration;
+					this.playTime += delta;
+					while (this.playTime >= animationDuration && animationDuration != 0) {
+						this.playTime -= animationDuration;
+					}
+					this.playTime = Math.max(0, Math.min(this.playTime, animationDuration));
+					this.timelineSlider.setValue(this.playTime / animationDuration);
+					this.animationState.update(delta);
+					this.animationState.apply(this.skeleton);
+					this.skeleton.updateWorldTransform();
+				}
+				var viewportSize = this.scale(this.config.viewport.width, this.config.viewport.height, this.canvas.width, this.canvas.height);
+				this.sceneRenderer.camera.zoom = this.config.viewport.width / viewportSize.x;
+				this.sceneRenderer.camera.position.x = this.config.viewport.x + this.config.viewport.width / 2;
+				this.sceneRenderer.camera.position.y = this.config.viewport.y + this.config.viewport.height / 2;
+				this.sceneRenderer.begin();
+				if (this.config.backgroundImage && this.config.backgroundImage.url) {
+					var bgImage = this.assetManager.get(this.config.backgroundImage.url);
+					if (!this.config.backgroundImage.x) {
+						this.sceneRenderer.drawTexture(bgImage, this.config.viewport.x, this.config.viewport.y, this.config.viewport.width, this.config.viewport.height);
+					}
+					else {
+						this.sceneRenderer.drawTexture(bgImage, this.config.backgroundImage.x, this.config.backgroundImage.y, this.config.backgroundImage.width, this.config.backgroundImage.height);
+					}
+				}
+				this.sceneRenderer.drawSkeleton(this.skeleton, this.config.premultipliedAlpha);
+				this.sceneRenderer.skeletonDebugRenderer.drawBones = this.config.debug.bones;
+				this.sceneRenderer.skeletonDebugRenderer.drawBoundingBoxes = this.config.debug.bounds;
+				this.sceneRenderer.skeletonDebugRenderer.drawClipping = this.config.debug.clipping;
+				this.sceneRenderer.skeletonDebugRenderer.drawMeshHull = this.config.debug.hulls;
+				this.sceneRenderer.skeletonDebugRenderer.drawPaths = this.config.debug.paths;
+				this.sceneRenderer.skeletonDebugRenderer.drawRegionAttachments = this.config.debug.regions;
+				this.sceneRenderer.skeletonDebugRenderer.drawMeshTriangles = this.config.debug.meshes;
+				this.sceneRenderer.drawSkeletonDebug(this.skeleton, this.config.premultipliedAlpha);
+				var controlBones = this.config.controlBones;
+				var selectedBones = this.selectedBones;
+				var skeleton = this.skeleton;
+				gl.lineWidth(2);
+				for (var i = 0; i < controlBones.length; i++) {
+					var bone = skeleton.findBone(controlBones[i]);
+					if (!bone)
+						continue;
+					var colorInner = selectedBones[i] !== null ? SpinePlayer.HOVER_COLOR_INNER : SpinePlayer.NON_HOVER_COLOR_INNER;
+					var colorOuter = selectedBones[i] !== null ? SpinePlayer.HOVER_COLOR_OUTER : SpinePlayer.NON_HOVER_COLOR_OUTER;
+					this.sceneRenderer.circle(true, skeleton.x + bone.worldX, skeleton.y + bone.worldY, 20, colorInner);
+					this.sceneRenderer.circle(false, skeleton.x + bone.worldX, skeleton.y + bone.worldY, 20, colorOuter);
+				}
+				gl.lineWidth(1);
+				this.sceneRenderer.end();
+				this.sceneRenderer.camera.zoom = 0;
+			}
+		};
+		SpinePlayer.prototype.scale = function (sourceWidth, sourceHeight, targetWidth, targetHeight) {
+			var targetRatio = targetHeight / targetWidth;
+			var sourceRatio = sourceHeight / sourceWidth;
+			var scale = targetRatio > sourceRatio ? targetWidth / sourceWidth : targetHeight / sourceHeight;
+			var temp = new spine.Vector2();
+			temp.x = sourceWidth * scale;
+			temp.y = sourceHeight * scale;
+			return temp;
+		};
+		SpinePlayer.prototype.loadSkeleton = function () {
+			var _this = this;
+			if (this.loaded)
+				return;
+			if (this.assetManager.hasErrors()) {
+				this.showError("Error: assets could not be loaded.<br><br>" + escapeHtml(JSON.stringify(this.assetManager.getErrors())));
+				return;
+			}
+			var atlas = this.assetManager.get(this.config.atlasUrl);
+			var jsonText = this.assetManager.get(this.config.jsonUrl);
+			var json = new spine.SkeletonJson(new spine.AtlasAttachmentLoader(atlas));
+			var skeletonData;
+			try {
+				skeletonData = json.readSkeletonData(jsonText);
+			}
+			catch (e) {
+				this.showError("Error: could not load skeleton .json.<br><br>" + escapeHtml(JSON.stringify(e)));
+				return;
+			}
+			this.skeleton = new spine.Skeleton(skeletonData);
+			var stateData = new spine.AnimationStateData(skeletonData);
+			stateData.defaultMix = 0.2;
+			this.animationState = new spine.AnimationState(stateData);
+			if (this.config.controlBones) {
+				this.config.controlBones.forEach(function (bone) {
+					if (!skeletonData.findBone(bone)) {
+						_this.showError("Error: control bone '" + bone + "' does not exist in skeleton.");
+					}
+				});
+			}
+			if (!this.config.skin) {
+				if (skeletonData.skins.length > 0) {
+					this.config.skin = skeletonData.skins[0].name;
+				}
+			}
+			if (this.config.skins && this.config.skin.length > 0) {
+				this.config.skins.forEach(function (skin) {
+					if (!_this.skeleton.data.findSkin(skin)) {
+						_this.showError("Error: skin '" + skin + "' in selectable skin list does not exist in skeleton.");
+						return;
+					}
+				});
+			}
+			if (this.config.skin) {
+				if (!this.skeleton.data.findSkin(this.config.skin)) {
+					this.showError("Error: skin '" + this.config.skin + "' does not exist in skeleton.");
+					return;
+				}
+				this.skeleton.setSkinByName(this.config.skin);
+				this.skeleton.setSlotsToSetupPose();
+			}
+			if (!this.config.viewport || !this.config.viewport.x || !this.config.viewport.y || !this.config.viewport.width || !this.config.viewport.height) {
+				this.config.viewport = {
+					x: 0,
+					y: 0,
+					width: 0,
+					height: 0
+				};
+				this.skeleton.updateWorldTransform();
+				var offset = new spine.Vector2();
+				var size = new spine.Vector2();
+				this.skeleton.getBounds(offset, size);
+				this.config.viewport.x = offset.x + size.x / 2 - size.x / 2 * 1.2;
+				this.config.viewport.y = offset.y + size.y / 2 - size.y / 2 * 1.2;
+				this.config.viewport.width = size.x * 1.2;
+				this.config.viewport.height = size.y * 1.2;
+			}
+			if (!this.config.animation) {
+				if (skeletonData.animations.length > 0) {
+					this.config.animation = skeletonData.animations[0].name;
+				}
+			}
+			if (this.config.animations && this.config.animations.length > 0) {
+				this.config.animations.forEach(function (animation) {
+					if (!_this.skeleton.data.findAnimation(animation)) {
+						_this.showError("Error: animation '" + animation + "' in selectable animation list does not exist in skeleton.");
+						return;
+					}
+				});
+			}
+			if (this.config.animation) {
+				if (!skeletonData.findAnimation(this.config.animation)) {
+					this.showError("Error: animation '" + this.config.animation + "' does not exist in skeleton.");
+					return;
+				}
+				this.play();
+				this.timelineSlider.change = function (percentage) {
+					_this.pause();
+					var animationDuration = _this.animationState.getCurrent(0).animation.duration;
+					var time = animationDuration * percentage;
+					_this.animationState.update(time - _this.playTime);
+					_this.animationState.apply(_this.skeleton);
+					_this.skeleton.updateWorldTransform();
+					_this.playTime = time;
+				};
+			}
+			this.setupInput();
+			this.loaded = true;
+		};
+		SpinePlayer.prototype.setupInput = function () {
+			var controlBones = this.config.controlBones;
+			var selectedBones = this.selectedBones = new Array(this.config.controlBones.length);
+			var canvas = this.canvas;
+			var input = new spine.webgl.Input(canvas);
+			var target = null;
+			var coords = new spine.webgl.Vector3();
+			var temp = new spine.webgl.Vector3();
+			var temp2 = new spine.Vector2();
+			var skeleton = this.skeleton;
+			var renderer = this.sceneRenderer;
+			input.addListener({
+				down: function (x, y) {
+					for (var i = 0; i < controlBones.length; i++) {
+						var bone = skeleton.findBone(controlBones[i]);
+						if (!bone)
+							continue;
+						renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.width, canvas.height);
+						if (temp.set(skeleton.x + bone.worldX, skeleton.y + bone.worldY, 0).distance(coords) < 30) {
+							target = bone;
+						}
+					}
+				},
+				up: function (x, y) {
+					target = null;
+				},
+				dragged: function (x, y) {
+					if (target != null) {
+						renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.width, canvas.height);
+						if (target.parent !== null) {
+							target.parent.worldToLocal(temp2.set(coords.x - skeleton.x, coords.y - skeleton.y));
+							target.x = temp2.x;
+							target.y = temp2.y;
+						}
+						else {
+							target.x = coords.x - skeleton.x;
+							target.y = coords.y - skeleton.y;
+						}
+					}
+				},
+				moved: function (x, y) {
+					for (var i = 0; i < controlBones.length; i++) {
+						var bone = skeleton.findBone(controlBones[i]);
+						if (!bone)
+							continue;
+						renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.width, canvas.height);
+						if (temp.set(skeleton.x + bone.worldX, skeleton.y + bone.worldY, 0).distance(coords) < 30) {
+							selectedBones[i] = bone;
+						}
+						else {
+							selectedBones[i] = null;
+						}
+					}
+				}
+			});
+		};
+		SpinePlayer.prototype.play = function () {
+			this.paused = false;
+			this.playButton.classList.remove("spine-player-button-icon-play");
+			this.playButton.classList.add("spine-player-button-icon-pause");
+			if (this.config.animation) {
+				if (!this.animationState.getCurrent(0)) {
+					this.animationState.setAnimation(0, this.config.animation, true);
+				}
+			}
+		};
+		SpinePlayer.prototype.pause = function () {
+			this.paused = true;
+			this.playButton.classList.remove("spine-player-button-icon-pause");
+			this.playButton.classList.add("spine-player-button-icon-play");
+		};
+		SpinePlayer.HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.25);
+		SpinePlayer.HOVER_COLOR_OUTER = new spine.Color(1, 1, 1, 1);
+		SpinePlayer.NON_HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.5);
+		SpinePlayer.NON_HOVER_COLOR_OUTER = new spine.Color(1, 0, 0, 0.8);
+		return SpinePlayer;
+	}());
+	spine.SpinePlayer = SpinePlayer;
+	function isContained(dom, needle) {
+		if (dom === needle)
+			return true;
+		var findRecursive = function (dom, needle) {
+			for (var i = 0; i < dom.children.length; i++) {
+				var child = dom.children[i];
+				if (child === needle)
+					return true;
+				if (findRecursive(child, needle))
+					return true;
+			}
+			return false;
+		};
+		return findRecursive(dom, needle);
+	}
+	function findWithId(dom, id) {
+		var found = new Array();
+		var findRecursive = function (dom, id, found) {
+			for (var i = 0; i < dom.children.length; i++) {
+				var child = dom.children[i];
+				if (child.id === id)
+					found.push(child);
+				findRecursive(child, id, found);
+			}
+		};
+		findRecursive(dom, id, found);
+		return found;
+	}
+	function findWithClass(dom, className) {
+		var found = new Array();
+		var findRecursive = function (dom, className, found) {
+			for (var i = 0; i < dom.children.length; i++) {
+				var child = dom.children[i];
+				if (child.classList.contains(className))
+					found.push(child);
+				findRecursive(child, className, found);
+			}
+		};
+		findRecursive(dom, className, found);
+		return found;
+	}
+	function createElement(html) {
+		var dom = document.createElement("div");
+		dom.innerHTML = html;
+		return dom.children[0];
+	}
+	function removeClass(elements, clazz) {
+		for (var i = 0; i < elements.length; i++) {
+			elements[i].classList.remove(clazz);
+		}
+	}
+	function escapeHtml(str) {
+		if (!str)
+			return "";
+		return str
+			.replace(/&/g, "&amp;")
+			.replace(/</g, "&lt;")
+			.replace(/>/g, "&gt;")
+			.replace(/"/g, "&#34;")
+			.replace(/'/g, "&#39;");
+	}
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var SpineWidget = (function () {
 		function SpineWidget(element, config) {

文件差异内容过多而无法显示
+ 0 - 0
spine-ts/build/spine-all.js.map


+ 26 - 26
spine-ts/build/spine-canvas.d.ts

@@ -16,11 +16,11 @@ declare module spine {
 		setup = 0,
 		first = 1,
 		replace = 2,
-		add = 3,
+		add = 3
 	}
 	enum MixDirection {
 		in = 0,
-		out = 1,
+		out = 1
 	}
 	enum TimelineType {
 		rotate = 0,
@@ -37,7 +37,7 @@ declare module spine {
 		pathConstraintPosition = 11,
 		pathConstraintSpacing = 12,
 		pathConstraintMix = 13,
-		twoColor = 14,
+		twoColor = 14
 	}
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
@@ -341,7 +341,7 @@ declare module spine {
 		end = 2,
 		dispose = 3,
 		complete = 4,
-		event = 5,
+		event = 5
 	}
 	interface AnimationStateListener2 {
 		start(entry: TrackEntry): void;
@@ -380,8 +380,8 @@ declare module spine {
 		private toLoad;
 		private loaded;
 		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		private static downloadText(url, success, error);
-		private static downloadBinary(url, success, error);
+		private static downloadText;
+		private static downloadBinary;
 		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
 		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
 		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
@@ -414,7 +414,7 @@ declare module spine {
 		Normal = 0,
 		Additive = 1,
 		Multiply = 2,
-		Screen = 3,
+		Screen = 3
 	}
 }
 declare module spine {
@@ -483,7 +483,7 @@ declare module spine {
 		OnlyTranslation = 1,
 		NoRotationOrReflection = 2,
 		NoScale = 3,
-		NoScaleOrReflection = 4,
+		NoScaleOrReflection = 4
 	}
 }
 declare module spine {
@@ -593,17 +593,17 @@ declare module spine {
 	}
 	enum PositionMode {
 		Fixed = 0,
-		Percent = 1,
+		Percent = 1
 	}
 	enum SpacingMode {
 		Length = 0,
 		Fixed = 1,
-		Percent = 2,
+		Percent = 2
 	}
 	enum RotateMode {
 		Tangent = 0,
 		Chain = 1,
-		ChainScale = 2,
+		ChainScale = 2
 	}
 }
 declare module spine {
@@ -614,12 +614,12 @@ declare module spine {
 		private rawAssets;
 		private errors;
 		constructor(pathPrefix?: string);
-		private queueAsset(clientId, textureLoader, path);
+		private queueAsset;
 		loadText(clientId: string, path: string): void;
 		loadJson(clientId: string, path: string): void;
 		loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
 		get(clientId: string, path: string): any;
-		private updateClientAssets(clientAssets);
+		private updateClientAssets;
 		isLoadingComplete(clientId: string): boolean;
 		dispose(): void;
 		hasErrors(): boolean;
@@ -670,7 +670,7 @@ declare module spine {
 		findIkConstraint(constraintName: string): IkConstraint;
 		findTransformConstraint(constraintName: string): TransformConstraint;
 		findPathConstraint(constraintName: string): PathConstraint;
-		getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
+		getBounds(offset: Vector2, size: Vector2, temp?: Array<number>): void;
 		update(delta: number): void;
 	}
 }
@@ -823,12 +823,12 @@ declare module spine {
 		MipMapNearestNearest = 9984,
 		MipMapLinearNearest = 9985,
 		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987,
+		MipMapLinearLinear = 9987
 	}
 	enum TextureWrap {
 		MirroredRepeat = 33648,
 		ClampToEdge = 33071,
-		Repeat = 10497,
+		Repeat = 10497
 	}
 	class TextureRegion {
 		renderObject: any;
@@ -855,7 +855,7 @@ declare module spine {
 		pages: TextureAtlasPage[];
 		regions: TextureAtlasRegion[];
 		constructor(atlasText: string, textureLoader: (path: string) => any);
-		private load(atlasText, textureLoader);
+		private load;
 		findRegion(name: string): TextureAtlasRegion;
 		dispose(): void;
 	}
@@ -931,9 +931,9 @@ declare module spine {
 		private polygonIndicesPool;
 		triangulate(verticesArray: ArrayLike<number>): Array<number>;
 		decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
-		private static isConcave(index, vertexCount, vertices, indices);
-		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
-		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static isConcave;
+		private static positiveArea;
+		private static winding;
 	}
 }
 declare module spine {
@@ -1105,7 +1105,7 @@ declare module spine {
 		Mesh = 2,
 		LinkedMesh = 3,
 		Path = 4,
-		Point = 5,
+		Point = 5
 	}
 }
 declare module spine {
@@ -1271,10 +1271,10 @@ declare module spine.canvas {
 		private tempColor;
 		constructor(context: CanvasRenderingContext2D);
 		draw(skeleton: Skeleton): void;
-		private drawImages(skeleton);
-		private drawTriangles(skeleton);
-		private drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
-		private computeRegionVertices(slot, region, pma);
-		private computeMeshVertices(slot, mesh, pma);
+		private drawImages;
+		private drawTriangles;
+		private drawTriangle;
+		private computeRegionVertices;
+		private computeMeshVertices;
 	}
 }

+ 7 - 3
spine-ts/build/spine-canvas.js

@@ -1,7 +1,10 @@
 var __extends = (this && this.__extends) || (function () {
-	var extendStatics = Object.setPrototypeOf ||
-		({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-		function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+	var extendStatics = function (d, b) {
+		extendStatics = Object.setPrototypeOf ||
+			({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+			function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+		return extendStatics(d, b);
+	}
 	return function (d, b) {
 		extendStatics(d, b);
 		function __() { this.constructor = d; }
@@ -3826,6 +3829,7 @@ var spine;
 			return null;
 		};
 		Skeleton.prototype.getBounds = function (offset, size, temp) {
+			if (temp === void 0) { temp = new Array(2); }
 			if (offset == null)
 				throw new Error("offset cannot be null.");
 			if (size == null)

文件差异内容过多而无法显示
+ 0 - 0
spine-ts/build/spine-canvas.js.map


+ 21 - 21
spine-ts/build/spine-core.d.ts

@@ -16,11 +16,11 @@ declare module spine {
 		setup = 0,
 		first = 1,
 		replace = 2,
-		add = 3,
+		add = 3
 	}
 	enum MixDirection {
 		in = 0,
-		out = 1,
+		out = 1
 	}
 	enum TimelineType {
 		rotate = 0,
@@ -37,7 +37,7 @@ declare module spine {
 		pathConstraintPosition = 11,
 		pathConstraintSpacing = 12,
 		pathConstraintMix = 13,
-		twoColor = 14,
+		twoColor = 14
 	}
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
@@ -341,7 +341,7 @@ declare module spine {
 		end = 2,
 		dispose = 3,
 		complete = 4,
-		event = 5,
+		event = 5
 	}
 	interface AnimationStateListener2 {
 		start(entry: TrackEntry): void;
@@ -380,8 +380,8 @@ declare module spine {
 		private toLoad;
 		private loaded;
 		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		private static downloadText(url, success, error);
-		private static downloadBinary(url, success, error);
+		private static downloadText;
+		private static downloadBinary;
 		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
 		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
 		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
@@ -414,7 +414,7 @@ declare module spine {
 		Normal = 0,
 		Additive = 1,
 		Multiply = 2,
-		Screen = 3,
+		Screen = 3
 	}
 }
 declare module spine {
@@ -483,7 +483,7 @@ declare module spine {
 		OnlyTranslation = 1,
 		NoRotationOrReflection = 2,
 		NoScale = 3,
-		NoScaleOrReflection = 4,
+		NoScaleOrReflection = 4
 	}
 }
 declare module spine {
@@ -593,17 +593,17 @@ declare module spine {
 	}
 	enum PositionMode {
 		Fixed = 0,
-		Percent = 1,
+		Percent = 1
 	}
 	enum SpacingMode {
 		Length = 0,
 		Fixed = 1,
-		Percent = 2,
+		Percent = 2
 	}
 	enum RotateMode {
 		Tangent = 0,
 		Chain = 1,
-		ChainScale = 2,
+		ChainScale = 2
 	}
 }
 declare module spine {
@@ -614,12 +614,12 @@ declare module spine {
 		private rawAssets;
 		private errors;
 		constructor(pathPrefix?: string);
-		private queueAsset(clientId, textureLoader, path);
+		private queueAsset;
 		loadText(clientId: string, path: string): void;
 		loadJson(clientId: string, path: string): void;
 		loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
 		get(clientId: string, path: string): any;
-		private updateClientAssets(clientAssets);
+		private updateClientAssets;
 		isLoadingComplete(clientId: string): boolean;
 		dispose(): void;
 		hasErrors(): boolean;
@@ -670,7 +670,7 @@ declare module spine {
 		findIkConstraint(constraintName: string): IkConstraint;
 		findTransformConstraint(constraintName: string): TransformConstraint;
 		findPathConstraint(constraintName: string): PathConstraint;
-		getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
+		getBounds(offset: Vector2, size: Vector2, temp?: Array<number>): void;
 		update(delta: number): void;
 	}
 }
@@ -823,12 +823,12 @@ declare module spine {
 		MipMapNearestNearest = 9984,
 		MipMapLinearNearest = 9985,
 		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987,
+		MipMapLinearLinear = 9987
 	}
 	enum TextureWrap {
 		MirroredRepeat = 33648,
 		ClampToEdge = 33071,
-		Repeat = 10497,
+		Repeat = 10497
 	}
 	class TextureRegion {
 		renderObject: any;
@@ -855,7 +855,7 @@ declare module spine {
 		pages: TextureAtlasPage[];
 		regions: TextureAtlasRegion[];
 		constructor(atlasText: string, textureLoader: (path: string) => any);
-		private load(atlasText, textureLoader);
+		private load;
 		findRegion(name: string): TextureAtlasRegion;
 		dispose(): void;
 	}
@@ -931,9 +931,9 @@ declare module spine {
 		private polygonIndicesPool;
 		triangulate(verticesArray: ArrayLike<number>): Array<number>;
 		decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
-		private static isConcave(index, vertexCount, vertices, indices);
-		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
-		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static isConcave;
+		private static positiveArea;
+		private static winding;
 	}
 }
 declare module spine {
@@ -1105,7 +1105,7 @@ declare module spine {
 		Mesh = 2,
 		LinkedMesh = 3,
 		Path = 4,
-		Point = 5,
+		Point = 5
 	}
 }
 declare module spine {

+ 7 - 3
spine-ts/build/spine-core.js

@@ -1,7 +1,10 @@
 var __extends = (this && this.__extends) || (function () {
-	var extendStatics = Object.setPrototypeOf ||
-		({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-		function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+	var extendStatics = function (d, b) {
+		extendStatics = Object.setPrototypeOf ||
+			({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+			function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+		return extendStatics(d, b);
+	}
 	return function (d, b) {
 		extendStatics(d, b);
 		function __() { this.constructor = d; }
@@ -3826,6 +3829,7 @@ var spine;
 			return null;
 		};
 		Skeleton.prototype.getBounds = function (offset, size, temp) {
+			if (temp === void 0) { temp = new Array(2); }
 			if (offset == null)
 				throw new Error("offset cannot be null.");
 			if (size == null)

文件差异内容过多而无法显示
+ 0 - 0
spine-ts/build/spine-core.js.map


+ 24 - 24
spine-ts/build/spine-threejs.d.ts

@@ -16,11 +16,11 @@ declare module spine {
 		setup = 0,
 		first = 1,
 		replace = 2,
-		add = 3,
+		add = 3
 	}
 	enum MixDirection {
 		in = 0,
-		out = 1,
+		out = 1
 	}
 	enum TimelineType {
 		rotate = 0,
@@ -37,7 +37,7 @@ declare module spine {
 		pathConstraintPosition = 11,
 		pathConstraintSpacing = 12,
 		pathConstraintMix = 13,
-		twoColor = 14,
+		twoColor = 14
 	}
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
@@ -341,7 +341,7 @@ declare module spine {
 		end = 2,
 		dispose = 3,
 		complete = 4,
-		event = 5,
+		event = 5
 	}
 	interface AnimationStateListener2 {
 		start(entry: TrackEntry): void;
@@ -380,8 +380,8 @@ declare module spine {
 		private toLoad;
 		private loaded;
 		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		private static downloadText(url, success, error);
-		private static downloadBinary(url, success, error);
+		private static downloadText;
+		private static downloadBinary;
 		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
 		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
 		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
@@ -414,7 +414,7 @@ declare module spine {
 		Normal = 0,
 		Additive = 1,
 		Multiply = 2,
-		Screen = 3,
+		Screen = 3
 	}
 }
 declare module spine {
@@ -483,7 +483,7 @@ declare module spine {
 		OnlyTranslation = 1,
 		NoRotationOrReflection = 2,
 		NoScale = 3,
-		NoScaleOrReflection = 4,
+		NoScaleOrReflection = 4
 	}
 }
 declare module spine {
@@ -593,17 +593,17 @@ declare module spine {
 	}
 	enum PositionMode {
 		Fixed = 0,
-		Percent = 1,
+		Percent = 1
 	}
 	enum SpacingMode {
 		Length = 0,
 		Fixed = 1,
-		Percent = 2,
+		Percent = 2
 	}
 	enum RotateMode {
 		Tangent = 0,
 		Chain = 1,
-		ChainScale = 2,
+		ChainScale = 2
 	}
 }
 declare module spine {
@@ -614,12 +614,12 @@ declare module spine {
 		private rawAssets;
 		private errors;
 		constructor(pathPrefix?: string);
-		private queueAsset(clientId, textureLoader, path);
+		private queueAsset;
 		loadText(clientId: string, path: string): void;
 		loadJson(clientId: string, path: string): void;
 		loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
 		get(clientId: string, path: string): any;
-		private updateClientAssets(clientAssets);
+		private updateClientAssets;
 		isLoadingComplete(clientId: string): boolean;
 		dispose(): void;
 		hasErrors(): boolean;
@@ -670,7 +670,7 @@ declare module spine {
 		findIkConstraint(constraintName: string): IkConstraint;
 		findTransformConstraint(constraintName: string): TransformConstraint;
 		findPathConstraint(constraintName: string): PathConstraint;
-		getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
+		getBounds(offset: Vector2, size: Vector2, temp?: Array<number>): void;
 		update(delta: number): void;
 	}
 }
@@ -823,12 +823,12 @@ declare module spine {
 		MipMapNearestNearest = 9984,
 		MipMapLinearNearest = 9985,
 		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987,
+		MipMapLinearLinear = 9987
 	}
 	enum TextureWrap {
 		MirroredRepeat = 33648,
 		ClampToEdge = 33071,
-		Repeat = 10497,
+		Repeat = 10497
 	}
 	class TextureRegion {
 		renderObject: any;
@@ -855,7 +855,7 @@ declare module spine {
 		pages: TextureAtlasPage[];
 		regions: TextureAtlasRegion[];
 		constructor(atlasText: string, textureLoader: (path: string) => any);
-		private load(atlasText, textureLoader);
+		private load;
 		findRegion(name: string): TextureAtlasRegion;
 		dispose(): void;
 	}
@@ -931,9 +931,9 @@ declare module spine {
 		private polygonIndicesPool;
 		triangulate(verticesArray: ArrayLike<number>): Array<number>;
 		decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
-		private static isConcave(index, vertexCount, vertices, indices);
-		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
-		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static isConcave;
+		private static positiveArea;
+		private static winding;
 	}
 }
 declare module spine {
@@ -1105,7 +1105,7 @@ declare module spine {
 		Mesh = 2,
 		LinkedMesh = 3,
 		Path = 4,
-		Point = 5,
+		Point = 5
 	}
 }
 declare module spine {
@@ -1290,9 +1290,9 @@ declare module spine.threejs {
 		private tempColor;
 		constructor(skeletonData: SkeletonData);
 		update(deltaTime: number): void;
-		private clearBatches();
-		private nextBatch();
-		private updateGeometry();
+		private clearBatches;
+		private nextBatch;
+		private updateGeometry;
 	}
 }
 declare module spine.threejs {

+ 7 - 3
spine-ts/build/spine-threejs.js

@@ -1,7 +1,10 @@
 var __extends = (this && this.__extends) || (function () {
-	var extendStatics = Object.setPrototypeOf ||
-		({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-		function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+	var extendStatics = function (d, b) {
+		extendStatics = Object.setPrototypeOf ||
+			({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+			function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+		return extendStatics(d, b);
+	}
 	return function (d, b) {
 		extendStatics(d, b);
 		function __() { this.constructor = d; }
@@ -3826,6 +3829,7 @@ var spine;
 			return null;
 		};
 		Skeleton.prototype.getBounds = function (offset, size, temp) {
+			if (temp === void 0) { temp = new Array(2); }
 			if (offset == null)
 				throw new Error("offset cannot be null.");
 			if (size == null)

文件差异内容过多而无法显示
+ 0 - 0
spine-ts/build/spine-threejs.js.map


+ 34 - 34
spine-ts/build/spine-webgl.d.ts

@@ -16,11 +16,11 @@ declare module spine {
 		setup = 0,
 		first = 1,
 		replace = 2,
-		add = 3,
+		add = 3
 	}
 	enum MixDirection {
 		in = 0,
-		out = 1,
+		out = 1
 	}
 	enum TimelineType {
 		rotate = 0,
@@ -37,7 +37,7 @@ declare module spine {
 		pathConstraintPosition = 11,
 		pathConstraintSpacing = 12,
 		pathConstraintMix = 13,
-		twoColor = 14,
+		twoColor = 14
 	}
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
@@ -341,7 +341,7 @@ declare module spine {
 		end = 2,
 		dispose = 3,
 		complete = 4,
-		event = 5,
+		event = 5
 	}
 	interface AnimationStateListener2 {
 		start(entry: TrackEntry): void;
@@ -380,8 +380,8 @@ declare module spine {
 		private toLoad;
 		private loaded;
 		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		private static downloadText(url, success, error);
-		private static downloadBinary(url, success, error);
+		private static downloadText;
+		private static downloadBinary;
 		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
 		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
 		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
@@ -414,7 +414,7 @@ declare module spine {
 		Normal = 0,
 		Additive = 1,
 		Multiply = 2,
-		Screen = 3,
+		Screen = 3
 	}
 }
 declare module spine {
@@ -483,7 +483,7 @@ declare module spine {
 		OnlyTranslation = 1,
 		NoRotationOrReflection = 2,
 		NoScale = 3,
-		NoScaleOrReflection = 4,
+		NoScaleOrReflection = 4
 	}
 }
 declare module spine {
@@ -593,17 +593,17 @@ declare module spine {
 	}
 	enum PositionMode {
 		Fixed = 0,
-		Percent = 1,
+		Percent = 1
 	}
 	enum SpacingMode {
 		Length = 0,
 		Fixed = 1,
-		Percent = 2,
+		Percent = 2
 	}
 	enum RotateMode {
 		Tangent = 0,
 		Chain = 1,
-		ChainScale = 2,
+		ChainScale = 2
 	}
 }
 declare module spine {
@@ -614,12 +614,12 @@ declare module spine {
 		private rawAssets;
 		private errors;
 		constructor(pathPrefix?: string);
-		private queueAsset(clientId, textureLoader, path);
+		private queueAsset;
 		loadText(clientId: string, path: string): void;
 		loadJson(clientId: string, path: string): void;
 		loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
 		get(clientId: string, path: string): any;
-		private updateClientAssets(clientAssets);
+		private updateClientAssets;
 		isLoadingComplete(clientId: string): boolean;
 		dispose(): void;
 		hasErrors(): boolean;
@@ -670,7 +670,7 @@ declare module spine {
 		findIkConstraint(constraintName: string): IkConstraint;
 		findTransformConstraint(constraintName: string): TransformConstraint;
 		findPathConstraint(constraintName: string): PathConstraint;
-		getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
+		getBounds(offset: Vector2, size: Vector2, temp?: Array<number>): void;
 		update(delta: number): void;
 	}
 }
@@ -823,12 +823,12 @@ declare module spine {
 		MipMapNearestNearest = 9984,
 		MipMapLinearNearest = 9985,
 		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987,
+		MipMapLinearLinear = 9987
 	}
 	enum TextureWrap {
 		MirroredRepeat = 33648,
 		ClampToEdge = 33071,
-		Repeat = 10497,
+		Repeat = 10497
 	}
 	class TextureRegion {
 		renderObject: any;
@@ -855,7 +855,7 @@ declare module spine {
 		pages: TextureAtlasPage[];
 		regions: TextureAtlasRegion[];
 		constructor(atlasText: string, textureLoader: (path: string) => any);
-		private load(atlasText, textureLoader);
+		private load;
 		findRegion(name: string): TextureAtlasRegion;
 		dispose(): void;
 	}
@@ -931,9 +931,9 @@ declare module spine {
 		private polygonIndicesPool;
 		triangulate(verticesArray: ArrayLike<number>): Array<number>;
 		decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
-		private static isConcave(index, vertexCount, vertices, indices);
-		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
-		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static isConcave;
+		private static positiveArea;
+		private static winding;
 	}
 }
 declare module spine {
@@ -1105,7 +1105,7 @@ declare module spine {
 		Mesh = 2,
 		LinkedMesh = 3,
 		Path = 4,
-		Point = 5,
+		Point = 5
 	}
 }
 declare module spine {
@@ -1299,7 +1299,7 @@ declare module spine.webgl {
 		touchesPool: Pool<Touch>;
 		private listeners;
 		constructor(element: HTMLElement);
-		private setupCallbacks(element);
+		private setupCallbacks;
 		addListener(listener: InputListener): void;
 		removeListener(listener: InputListener): void;
 	}
@@ -1408,7 +1408,7 @@ declare module spine.webgl {
 		drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
 		bind(shader: Shader): void;
 		unbind(shader: Shader): void;
-		private update();
+		private update;
 		restore(): void;
 		dispose(): void;
 	}
@@ -1434,7 +1434,7 @@ declare module spine.webgl {
 		constructor();
 	}
 	enum VertexAttributeType {
-		Float = 0,
+		Float = 0
 	}
 }
 declare module spine.webgl {
@@ -1453,7 +1453,7 @@ declare module spine.webgl {
 		begin(shader: Shader): void;
 		setBlendMode(srcBlend: number, dstBlend: number): void;
 		draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
-		private flush();
+		private flush;
 		end(): void;
 		getDrawCalls(): number;
 		dispose(): void;
@@ -1493,13 +1493,13 @@ declare module spine.webgl {
 		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
 		end(): void;
 		resize(resizeMode: ResizeMode): void;
-		private enableRenderer(renderer);
+		private enableRenderer;
 		dispose(): void;
 	}
 	enum ResizeMode {
 		Stretch = 0,
 		Expand = 1,
-		Fit = 2,
+		Fit = 2
 	}
 }
 declare module spine.webgl {
@@ -1527,9 +1527,9 @@ declare module spine.webgl {
 		getVertexShaderSource(): string;
 		getFragmentSource(): string;
 		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, vertexShader: string, fragmentShader: string);
-		private compile();
-		private compileShader(type, source);
-		private compileProgram(vs, fs);
+		private compile;
+		private compileShader;
+		private compileProgram;
 		restore(): void;
 		bind(): void;
 		unbind(): void;
@@ -1576,16 +1576,16 @@ declare module spine.webgl {
 		polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
 		circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
 		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
-		private vertex(x, y, color);
+		private vertex;
 		end(): void;
-		private flush();
-		private check(shapeType, numVertices);
+		private flush;
+		private check;
 		dispose(): void;
 	}
 	enum ShapeType {
 		Point = 0,
 		Line = 1,
-		Filled = 4,
+		Filled = 4
 	}
 }
 declare module spine.webgl {

+ 21 - 10
spine-ts/build/spine-webgl.js

@@ -1,7 +1,10 @@
 var __extends = (this && this.__extends) || (function () {
-	var extendStatics = Object.setPrototypeOf ||
-		({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-		function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+	var extendStatics = function (d, b) {
+		extendStatics = Object.setPrototypeOf ||
+			({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+			function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+		return extendStatics(d, b);
+	}
 	return function (d, b) {
 		extendStatics(d, b);
 		function __() { this.constructor = d; }
@@ -3826,6 +3829,7 @@ var spine;
 			return null;
 		};
 		Skeleton.prototype.getBounds = function (offset, size, temp) {
+			if (temp === void 0) { temp = new Array(2); }
 			if (offset == null)
 				throw new Error("offset cannot be null.");
 			if (size == null)
@@ -6960,7 +6964,7 @@ var spine;
 			}
 			Input.prototype.setupCallbacks = function (element) {
 				var _this = this;
-				element.addEventListener("mousedown", function (ev) {
+				var mouseDown = function (ev) {
 					if (ev instanceof MouseEvent) {
 						var rect = element.getBoundingClientRect();
 						var x = ev.clientX - rect.left;
@@ -6972,9 +6976,11 @@ var spine;
 						_this.lastX = x;
 						_this.lastY = y;
 						_this.buttonDown = true;
+						document.addEventListener("mousemove", mouseMove);
+						document.addEventListener("mouseup", mouseUp);
 					}
-				}, true);
-				element.addEventListener("mousemove", function (ev) {
+				};
+				var mouseMove = function (ev) {
 					if (ev instanceof MouseEvent) {
 						var rect = element.getBoundingClientRect();
 						var x = ev.clientX - rect.left;
@@ -6991,8 +6997,8 @@ var spine;
 						_this.lastX = x;
 						_this.lastY = y;
 					}
-				}, true);
-				element.addEventListener("mouseup", function (ev) {
+				};
+				var mouseUp = function (ev) {
 					if (ev instanceof MouseEvent) {
 						var rect = element.getBoundingClientRect();
 						var x = ev.clientX - rect.left;
@@ -7004,8 +7010,13 @@ var spine;
 						_this.lastX = x;
 						_this.lastY = y;
 						_this.buttonDown = false;
+						document.removeEventListener("mousemove", mouseMove);
+						document.removeEventListener("mouseup", mouseUp);
 					}
-				}, true);
+				};
+				element.addEventListener("mousedown", mouseDown, true);
+				element.addEventListener("mousemove", mouseMove, true);
+				element.addEventListener("mouseup", mouseUp, true);
 				element.addEventListener("touchstart", function (ev) {
 					if (_this.currTouch != null)
 						return;
@@ -7167,11 +7178,11 @@ var spine;
 				var renderer = this.renderer;
 				var canvas = renderer.canvas;
 				var gl = renderer.context.gl;
+				renderer.resize(webgl.ResizeMode.Stretch);
 				var oldX = renderer.camera.position.x, oldY = renderer.camera.position.y;
 				renderer.camera.position.set(canvas.width / 2, canvas.height / 2, 0);
 				renderer.camera.viewportWidth = canvas.width;
 				renderer.camera.viewportHeight = canvas.height;
-				renderer.resize(webgl.ResizeMode.Stretch);
 				if (!complete) {
 					gl.clearColor(this.backgroundColor.r, this.backgroundColor.g, this.backgroundColor.b, this.backgroundColor.a);
 					gl.clear(gl.COLOR_BUFFER_BIT);

文件差异内容过多而无法显示
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 75 - 50
spine-ts/build/spine-widget.d.ts

@@ -16,11 +16,11 @@ declare module spine {
         setup = 0,
         first = 1,
         replace = 2,
-        add = 3
+        add = 3,
     }
     enum MixDirection {
         in = 0,
-        out = 1
+        out = 1,
     }
     enum TimelineType {
         rotate = 0,
@@ -37,7 +37,7 @@ declare module spine {
         pathConstraintPosition = 11,
         pathConstraintSpacing = 12,
         pathConstraintMix = 13,
-        twoColor = 14
+        twoColor = 14,
     }
     abstract class CurveTimeline implements Timeline {
         static LINEAR: number;
@@ -341,7 +341,7 @@ declare module spine {
         end = 2,
         dispose = 3,
         complete = 4,
-        event = 5
+        event = 5,
     }
     interface AnimationStateListener2 {
         start(entry: TrackEntry): void;
@@ -380,8 +380,8 @@ declare module spine {
         private toLoad;
         private loaded;
         constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-        private static downloadText;
-        private static downloadBinary;
+        private static downloadText(url, success, error);
+        private static downloadBinary(url, success, error);
         loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
         loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
         loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
@@ -414,7 +414,7 @@ declare module spine {
         Normal = 0,
         Additive = 1,
         Multiply = 2,
-        Screen = 3
+        Screen = 3,
     }
 }
 declare module spine {
@@ -483,7 +483,7 @@ declare module spine {
         OnlyTranslation = 1,
         NoRotationOrReflection = 2,
         NoScale = 3,
-        NoScaleOrReflection = 4
+        NoScaleOrReflection = 4,
     }
 }
 declare module spine {
@@ -593,17 +593,17 @@ declare module spine {
     }
     enum PositionMode {
         Fixed = 0,
-        Percent = 1
+        Percent = 1,
     }
     enum SpacingMode {
         Length = 0,
         Fixed = 1,
-        Percent = 2
+        Percent = 2,
     }
     enum RotateMode {
         Tangent = 0,
         Chain = 1,
-        ChainScale = 2
+        ChainScale = 2,
     }
 }
 declare module spine {
@@ -614,12 +614,12 @@ declare module spine {
         private rawAssets;
         private errors;
         constructor(pathPrefix?: string);
-        private queueAsset;
+        private queueAsset(clientId, textureLoader, path);
         loadText(clientId: string, path: string): void;
         loadJson(clientId: string, path: string): void;
         loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
         get(clientId: string, path: string): any;
-        private updateClientAssets;
+        private updateClientAssets(clientAssets);
         isLoadingComplete(clientId: string): boolean;
         dispose(): void;
         hasErrors(): boolean;
@@ -823,12 +823,12 @@ declare module spine {
         MipMapNearestNearest = 9984,
         MipMapLinearNearest = 9985,
         MipMapNearestLinear = 9986,
-        MipMapLinearLinear = 9987
+        MipMapLinearLinear = 9987,
     }
     enum TextureWrap {
         MirroredRepeat = 33648,
         ClampToEdge = 33071,
-        Repeat = 10497
+        Repeat = 10497,
     }
     class TextureRegion {
         renderObject: any;
@@ -855,7 +855,7 @@ declare module spine {
         pages: TextureAtlasPage[];
         regions: TextureAtlasRegion[];
         constructor(atlasText: string, textureLoader: (path: string) => any);
-        private load;
+        private load(atlasText, textureLoader);
         findRegion(name: string): TextureAtlasRegion;
         dispose(): void;
     }
@@ -931,9 +931,9 @@ declare module spine {
         private polygonIndicesPool;
         triangulate(verticesArray: ArrayLike<number>): Array<number>;
         decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
-        private static isConcave;
-        private static positiveArea;
-        private static winding;
+        private static isConcave(index, vertexCount, vertices, indices);
+        private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+        private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
     }
 }
 declare module spine {
@@ -1105,7 +1105,7 @@ declare module spine {
         Mesh = 2,
         LinkedMesh = 3,
         Path = 4,
-        Point = 5
+        Point = 5,
     }
 }
 declare module spine {
@@ -1299,7 +1299,7 @@ declare module spine.webgl {
         touchesPool: Pool<Touch>;
         private listeners;
         constructor(element: HTMLElement);
-        private setupCallbacks;
+        private setupCallbacks(element);
         addListener(listener: InputListener): void;
         removeListener(listener: InputListener): void;
     }
@@ -1408,7 +1408,7 @@ declare module spine.webgl {
         drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
         bind(shader: Shader): void;
         unbind(shader: Shader): void;
-        private update;
+        private update();
         restore(): void;
         dispose(): void;
     }
@@ -1434,7 +1434,7 @@ declare module spine.webgl {
         constructor();
     }
     enum VertexAttributeType {
-        Float = 0
+        Float = 0,
     }
 }
 declare module spine.webgl {
@@ -1453,7 +1453,7 @@ declare module spine.webgl {
         begin(shader: Shader): void;
         setBlendMode(srcBlend: number, dstBlend: number): void;
         draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
-        private flush;
+        private flush();
         end(): void;
         getDrawCalls(): number;
         dispose(): void;
@@ -1493,13 +1493,13 @@ declare module spine.webgl {
         curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
         end(): void;
         resize(resizeMode: ResizeMode): void;
-        private enableRenderer;
+        private enableRenderer(renderer);
         dispose(): void;
     }
     enum ResizeMode {
         Stretch = 0,
         Expand = 1,
-        Fit = 2
+        Fit = 2,
     }
 }
 declare module spine.webgl {
@@ -1527,9 +1527,9 @@ declare module spine.webgl {
         getVertexShaderSource(): string;
         getFragmentSource(): string;
         constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, vertexShader: string, fragmentShader: string);
-        private compile;
-        private compileShader;
-        private compileProgram;
+        private compile();
+        private compileShader(type, source);
+        private compileProgram(vs, fs);
         restore(): void;
         bind(): void;
         unbind(): void;
@@ -1576,16 +1576,16 @@ declare module spine.webgl {
         polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
         circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
         curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
-        private vertex;
+        private vertex(x, y, color);
         end(): void;
-        private flush;
-        private check;
+        private flush();
+        private check(shapeType, numVertices);
         dispose(): void;
     }
     enum ShapeType {
         Point = 0,
         Line = 1,
-        Filled = 4
+        Filled = 4,
     }
 }
 declare module spine.webgl {
@@ -1687,16 +1687,21 @@ declare module spine {
         jsonUrl: string;
         atlasUrl: string;
         animation: string;
+        animations: string[];
         skin: string;
+        skins: string[];
+        controlBones: string[];
+        premultipliedAlpha: boolean;
+        showControls: boolean;
         debug: {
             bones: boolean;
             regions: boolean;
+            meshes: boolean;
             bounds: boolean;
             paths: boolean;
-            points: boolean;
             clipping: boolean;
-            meshHull: boolean;
-            triangles: boolean;
+            points: boolean;
+            hulls: boolean;
         };
         viewport: {
             x: number;
@@ -1706,19 +1711,33 @@ declare module spine {
         };
         alpha: boolean;
         backgroundColor: string;
-        premultipliedAlpha: boolean;
-        success: (widget: SpineWidget) => void;
-        error: (widget: SpineWidget, msg: string) => void;
+        backgroundImage: {
+            url: string;
+            x: number;
+            y: number;
+            width: number;
+            height: number;
+        };
+        success: (widget: SpinePlayer) => void;
+        error: (widget: SpinePlayer, msg: string) => void;
     }
     class SpinePlayer {
         private config;
+        static HOVER_COLOR_INNER: Color;
+        static HOVER_COLOR_OUTER: Color;
+        static NON_HOVER_COLOR_INNER: Color;
+        static NON_HOVER_COLOR_OUTER: Color;
         private sceneRenderer;
+        private dom;
+        private playerControls;
         private canvas;
+        private timelineSlider;
+        private playButton;
+        private skinButton;
+        private animationButton;
         private context;
         private loadingScreen;
         private assetManager;
-        private timelineSlider;
-        private playButton;
         private loaded;
         private skeleton;
         private animationState;
@@ -1726,15 +1745,21 @@ declare module spine {
         private paused;
         private playTime;
         private speed;
+        private selectedBones;
         constructor(parent: HTMLElement, config: SpinePlayerConfig);
         validateConfig(config: SpinePlayerConfig): SpinePlayerConfig;
-        render(parent: HTMLElement, config: SpinePlayerConfig): void;
+        showError(error: string): void;
+        render(): HTMLElement;
+        showSpeedDialog(): void;
+        showAnimationsDialog(): void;
+        showSkinsDialog(): void;
+        showSettingsDialog(): void;
         drawFrame(requestNextFrame?: boolean): void;
         scale(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): Vector2;
         loadSkeleton(): void;
-        private play;
-        private pause;
-        private resize;
+        setupInput(): void;
+        private play();
+        private pause();
     }
 }
 declare module spine {
@@ -1758,10 +1783,10 @@ declare module spine {
         private loaded;
         private bounds;
         constructor(element: HTMLElement | string, config: SpineWidgetConfig);
-        private validateConfig;
-        private load;
-        private render;
-        private resize;
+        private validateConfig(config);
+        private load();
+        private render();
+        private resize();
         pause(): void;
         play(): void;
         isPlaying(): boolean;
@@ -1769,7 +1794,7 @@ declare module spine {
         static loadWidgets(): void;
         static loadWidget(widget: HTMLElement): void;
         static pageLoaded: boolean;
-        private static ready;
+        private static ready();
         static setupDOMListener(): void;
     }
     class SpineWidgetConfig {

+ 424 - 152
spine-ts/build/spine-widget.js

@@ -1,10 +1,7 @@
 var __extends = (this && this.__extends) || (function () {
-    var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-    }
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
     return function (d, b) {
         extendStatics(d, b);
         function __() { this.constructor = d; }
@@ -9404,12 +9401,68 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
+    var Popup = (function () {
+        function Popup(parent, htmlContent) {
+            this.dom = createElement("\n\t\t\t\t<div class=\"spine-player-popup spine-player-hidden\">\n\t\t\t\t</div>\n\t\t\t");
+            this.dom.innerHTML = htmlContent;
+            parent.appendChild(this.dom);
+        }
+        Popup.prototype.show = function () {
+            var _this = this;
+            this.dom.classList.remove("spine-player-hidden");
+            var justClicked = true;
+            var windowClickListener = function (event) {
+                if (justClicked) {
+                    justClicked = false;
+                    return;
+                }
+                if (!isContained(_this.dom, event.target)) {
+                    _this.dom.parentNode.removeChild(_this.dom);
+                    window.removeEventListener("click", windowClickListener);
+                }
+            };
+            window.addEventListener("click", windowClickListener);
+        };
+        return Popup;
+    }());
+    var Switch = (function () {
+        function Switch(text) {
+            this.text = text;
+            this.enabled = false;
+        }
+        Switch.prototype.render = function () {
+            var _this = this;
+            this["switch"] = createElement("\n\t\t\t\t<div class=\"spine-player-switch\">\n\t\t\t\t\t<span class=\"spine-player-switch-text\">" + this.text + "</span>\n\t\t\t\t\t<div class=\"spine-player-switch-knob-area\">\n\t\t\t\t\t\t<div class=\"spine-player-switch-knob\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t");
+            this["switch"].addEventListener("click", function () {
+                _this.setEnabled(!_this.enabled);
+                if (_this.change)
+                    _this.change(_this.enabled);
+            });
+            return this["switch"];
+        };
+        Switch.prototype.setEnabled = function (enabled) {
+            if (enabled)
+                this["switch"].classList.add("active");
+            else
+                this["switch"].classList.remove("active");
+            this.enabled = enabled;
+        };
+        Switch.prototype.isEnabled = function () {
+            return this.enabled;
+        };
+        return Switch;
+    }());
     var Slider = (function () {
-        function Slider(parent) {
+        function Slider(snaps, snapPercentage) {
+            if (snaps === void 0) { snaps = 0; }
+            if (snapPercentage === void 0) { snapPercentage = 0.1; }
+            this.snaps = snaps;
+            this.snapPercentage = snapPercentage;
+        }
+        Slider.prototype.render = function () {
             var _this = this;
-            parent.innerHTML = "\n\t\t\t\t<div class=\"spine-player-slider\">\n\t\t\t\t\t<div class=\"spine-player-slider-value\"></div>\n\t\t\t\t</div>\n\t\t\t";
-            this.slider = findWithClass(parent, "spine-player-slider")[0];
-            this.value = findWithClass(parent, "spine-player-slider-value")[0];
+            this.slider = createElement("\n\t\t\t\t<div class=\"spine-player-slider\">\n\t\t\t\t\t<div class=\"spine-player-slider-value\"></div>\n\t\t\t\t</div>\n\t\t\t");
+            this.value = findWithClass(this.slider, "spine-player-slider-value")[0];
             this.setValue(0);
             var input = new spine.webgl.Input(this.slider);
             var dragging = false;
@@ -9420,7 +9473,7 @@ var spine;
                 up: function (x, y) {
                     dragging = false;
                     var percentage = x / _this.slider.clientWidth;
-                    percentage = Math.max(0, Math.min(percentage, 1));
+                    percentage = percentage = Math.max(0, Math.min(percentage, 1));
                     _this.setValue(x / _this.slider.clientWidth);
                     if (_this.change)
                         _this.change(percentage);
@@ -9429,7 +9482,7 @@ var spine;
                     if (dragging) {
                         var percentage = x / _this.slider.clientWidth;
                         percentage = Math.max(0, Math.min(percentage, 1));
-                        _this.setValue(x / _this.slider.clientWidth);
+                        percentage = _this.setValue(x / _this.slider.clientWidth);
                         if (_this.change)
                             _this.change(percentage);
                     }
@@ -9437,15 +9490,27 @@ var spine;
                 dragged: function (x, y) {
                     var percentage = x / _this.slider.clientWidth;
                     percentage = Math.max(0, Math.min(percentage, 1));
-                    _this.setValue(x / _this.slider.clientWidth);
+                    percentage = _this.setValue(x / _this.slider.clientWidth);
                     if (_this.change)
                         _this.change(percentage);
                 }
             });
-        }
+            return this.slider;
+        };
         Slider.prototype.setValue = function (percentage) {
             percentage = Math.max(0, Math.min(1, percentage));
+            if (this.snaps > 0) {
+                var modulo = percentage % (1 / this.snaps);
+                if (modulo < (1 / this.snaps) * this.snapPercentage) {
+                    percentage = percentage - modulo;
+                }
+                else if (modulo > (1 / this.snaps) - (1 / this.snaps) * this.snapPercentage) {
+                    percentage = percentage - modulo + (1 / this.snaps);
+                }
+                percentage = Math.max(0, Math.min(1, percentage));
+            }
             this.value.style.width = "" + (percentage * 100) + "%";
+            return percentage;
         };
         return Slider;
     }());
@@ -9456,8 +9521,7 @@ var spine;
             this.paused = true;
             this.playTime = 0;
             this.speed = 1;
-            this.validateConfig(config);
-            this.render(parent, config);
+            parent.appendChild(this.render());
         }
         SpinePlayer.prototype.validateConfig = function (config) {
             if (!config)
@@ -9479,13 +9543,13 @@ var spine;
             if (!config.debug)
                 config.debug = {
                     bones: false,
+                    regions: false,
+                    meshes: false,
                     bounds: false,
                     clipping: false,
-                    meshHull: false,
                     paths: false,
                     points: false,
-                    regions: false,
-                    triangles: false
+                    hulls: false
                 };
             if (!config.debug.bones)
                 config.debug.bones = false;
@@ -9493,50 +9557,74 @@ var spine;
                 config.debug.bounds = false;
             if (!config.debug.clipping)
                 config.debug.clipping = false;
-            if (!config.debug.meshHull)
-                config.debug.meshHull = false;
+            if (!config.debug.hulls)
+                config.debug.hulls = false;
             if (!config.debug.paths)
                 config.debug.paths = false;
             if (!config.debug.points)
                 config.debug.points = false;
             if (!config.debug.regions)
                 config.debug.regions = false;
-            if (!config.debug.triangles)
-                config.debug.triangles = false;
+            if (!config.debug.meshes)
+                config.debug.meshes = false;
+            if (config.animations && config.animation) {
+                if (config.animations.indexOf(config.animation) < 0)
+                    throw new Error("Default animation '" + config.animation + "' is not contained in the list of selectable animations " + escapeHtml(JSON.stringify(this.config.animations)) + ".");
+            }
+            if (config.skins && config.skin) {
+                if (config.skins.indexOf(config.skin) < 0)
+                    throw new Error("Default skin '" + config.skin + "' is not contained in the list of selectable skins " + escapeHtml(JSON.stringify(this.config.skins)) + ".");
+            }
+            if (!config.controlBones)
+                config.controlBones = [];
+            if (!config.showControls)
+                config.showControls = true;
             return config;
         };
-        SpinePlayer.prototype.render = function (parent, config) {
+        SpinePlayer.prototype.showError = function (error) {
+            var errorDom = findWithClass(this.dom, "spine-player-error")[0];
+            errorDom.classList.remove("spine-player-hidden");
+            errorDom.innerHTML = "<p style=\"text-align: center; align-self: center;\">" + error + "</p>";
+            this.config.error(this, error);
+        };
+        SpinePlayer.prototype.render = function () {
             var _this = this;
-            parent.innerHTML = "\n\t\t\t\t<div class=\"spine-player\">\n\t\t\t\t\t<canvas class=\"spine-player-canvas\"></canvas>\n\t\t\t\t\t<div class=\"spine-player-controls spine-player-dropdown\">\n\t\t\t\t\t\t<div class=\"spine-player-timeline\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"spine-player-buttons\">\n\t\t\t\t\t\t\t<button id=\"spine-player-button-play-pause\" class=\"spine-player-button spine-player-button-icon-pause\"></button>\n\t\t\t\t\t\t\t<div class=\"spine-player-button-spacer\"></div>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-speed\" class=\"spine-player-button spine-player-button-icon-speed\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-animation\" class=\"spine-player-button spine-player-button-icon-animations\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-skin\" class=\"spine-player-button spine-player-button-icon-skins\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-settings\" class=\"spine-player-button spine-player-button-icon-settings\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-fullscreen\" class=\"spine-player-button spine-player-button-icon-fullscreen\"></button>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"spine-player-dropdown-content spine-player-hidden\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t";
-            this.canvas = findWithClass(parent, "spine-player-canvas")[0];
-            var webglConfig = { alpha: config.alpha };
-            this.context = new spine.webgl.ManagedWebGLRenderingContext(this.canvas, webglConfig);
-            this.sceneRenderer = new spine.webgl.SceneRenderer(this.canvas, this.context, true);
-            this.loadingScreen = new spine.webgl.LoadingScreen(this.sceneRenderer);
+            var config = this.config;
+            var dom = this.dom = createElement("\n\t\t\t\t<div class=\"spine-player\">\n\t\t\t\t\t<canvas class=\"spine-player-canvas\"></canvas>\n\t\t\t\t\t<div class=\"spine-player-error spine-player-hidden\"></div>\n\t\t\t\t\t<div class=\"spine-player-controls spine-player-popup-parent hidden\">\n\t\t\t\t\t\t<div class=\"spine-player-timeline\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"spine-player-buttons\">\n\t\t\t\t\t\t\t<button id=\"spine-player-button-play-pause\" class=\"spine-player-button spine-player-button-icon-pause\"></button>\n\t\t\t\t\t\t\t<div class=\"spine-player-button-spacer\"></div>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-speed\" class=\"spine-player-button spine-player-button-icon-speed\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-animation\" class=\"spine-player-button spine-player-button-icon-animations\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-skin\" class=\"spine-player-button spine-player-button-icon-skins\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-settings\" class=\"spine-player-button spine-player-button-icon-settings\"></button>\n\t\t\t\t\t\t\t<button id=\"spine-player-button-fullscreen\" class=\"spine-player-button spine-player-button-icon-fullscreen\"></button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t");
+            try {
+                this.config = this.validateConfig(config);
+            }
+            catch (e) {
+                this.showError(e);
+                return dom;
+            }
+            try {
+                this.canvas = findWithClass(dom, "spine-player-canvas")[0];
+                var webglConfig = { alpha: config.alpha };
+                this.context = new spine.webgl.ManagedWebGLRenderingContext(this.canvas, webglConfig);
+                this.sceneRenderer = new spine.webgl.SceneRenderer(this.canvas, this.context, true);
+                this.loadingScreen = new spine.webgl.LoadingScreen(this.sceneRenderer);
+            }
+            catch (e) {
+                this.showError("Sorry, your browser does not support WebGL.<br><br>Please use the latest version of Firefox, Chrome, Edge, or Safari.");
+                return dom;
+            }
             this.assetManager = new spine.webgl.AssetManager(this.context);
             this.assetManager.loadText(config.jsonUrl);
             this.assetManager.loadTextureAtlas(config.atlasUrl);
+            if (config.backgroundImage && config.backgroundImage.url)
+                this.assetManager.loadTexture(config.backgroundImage.url);
             requestAnimationFrame(function () { return _this.drawFrame(); });
-            var timeline = findWithClass(parent, "spine-player-timeline")[0];
-            this.timelineSlider = new Slider(timeline);
-            this.playButton = findWithId(parent, "spine-player-button-play-pause")[0];
-            var speedButton = findWithId(parent, "spine-player-button-speed")[0];
-            var animationButton = findWithId(parent, "spine-player-button-animation")[0];
-            var skinButton = findWithId(parent, "spine-player-button-skin")[0];
-            var settingsButton = findWithId(parent, "spine-player-button-settings")[0];
-            var fullscreenButton = findWithId(parent, "spine-player-button-fullscreen")[0];
-            var dropdown = findWithClass(parent, "spine-player-dropdown-content")[0];
-            var justClicked = false;
-            var dismissDropdown = function (event) {
-                if (justClicked) {
-                    justClicked = false;
-                    return;
-                }
-                if (!isContained(dropdown, event.target)) {
-                    dropdown.classList.add("spine-player-hidden");
-                    window.onclick = null;
-                }
-            };
+            this.playerControls = findWithClass(dom, "spine-player-controls")[0];
+            var timeline = findWithClass(dom, "spine-player-timeline")[0];
+            this.timelineSlider = new Slider();
+            timeline.appendChild(this.timelineSlider.render());
+            this.playButton = findWithId(dom, "spine-player-button-play-pause")[0];
+            var speedButton = findWithId(dom, "spine-player-button-speed")[0];
+            this.animationButton = findWithId(dom, "spine-player-button-animation")[0];
+            this.skinButton = findWithId(dom, "spine-player-button-skin")[0];
+            var settingsButton = findWithId(dom, "spine-player-button-settings")[0];
+            var fullscreenButton = findWithId(dom, "spine-player-button-fullscreen")[0];
             this.playButton.onclick = function () {
                 if (_this.paused)
                     _this.play();
@@ -9544,94 +9632,16 @@ var spine;
                     _this.pause();
             };
             speedButton.onclick = function () {
-                dropdown.classList.remove("spine-player-hidden");
-                dropdown.innerHTML = "\n\t\t\t\t\t<div class=\"spine-player-row\" style=\"user-select: none; align-items: center;\">\n\t\t\t\t\t\t<div style=\"margin-right: 16px;\">Speed</div>\n\t\t\t\t\t\t<div class=\"spine-player-column\">\n\t\t\t\t\t\t\t<div class=\"spine-player-speed-slider\" style=\"margin-bottom: 4px;\"></div>\n\t\t\t\t\t\t\t<div class=\"spine-player-row\" style=\"justify-content: space-between;\">\n\t\t\t\t\t\t\t\t<div>0.1x</div>\n\t\t\t\t\t\t\t\t<div>1x</div>\n\t\t\t\t\t\t\t\t<div>2x</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t";
-                var sliderParent = findWithClass(dropdown, "spine-player-speed-slider")[0];
-                var slider = new Slider(sliderParent);
-                slider.setValue(_this.speed / 2);
-                slider.change = function (percentage) {
-                    _this.speed = percentage * 2;
-                };
-                justClicked = true;
-                window.onclick = dismissDropdown;
+                _this.showSpeedDialog();
             };
-            animationButton.onclick = function () {
-                if (!_this.skeleton || _this.skeleton.data.animations.length == 0)
-                    return;
-                dropdown.classList.remove("spine-player-hidden");
-                dropdown.innerHTML = "\n\t\t\t\t\t<div class=\"spine-player-dropdown-title\">Animations</div>\n\t\t\t\t\t<hr>\n\t\t\t\t\t<ul class=\"spine-player-list\">\n\t\t\t\t\t</ul>\n\t\t\t\t";
-                var rows = findWithClass(dropdown, "spine-player-list")[0];
-                _this.skeleton.data.animations.forEach(function (animation) {
-                    var row = document.createElement("li");
-                    row.classList.add("spine-player-list-item");
-                    if (animation.name == _this.config.animation)
-                        row.classList.add("spine-player-list-item-selected");
-                    row.innerText = animation.name;
-                    rows.appendChild(row);
-                    row.onclick = function () {
-                        removeClass(rows.children, "spine-player-list-item-selected");
-                        row.classList.add("spine-player-list-item-selected");
-                        _this.config.animation = animation.name;
-                        _this.playTime = 0;
-                        _this.animationState.setAnimation(0, _this.config.animation, true);
-                    };
-                });
-                justClicked = true;
-                window.onclick = dismissDropdown;
+            this.animationButton.onclick = function () {
+                _this.showAnimationsDialog();
             };
-            skinButton.onclick = function () {
-                if (!_this.skeleton || _this.skeleton.data.animations.length == 0)
-                    return;
-                dropdown.classList.remove("spine-player-hidden");
-                dropdown.innerHTML = "\n\t\t\t\t\t<div class=\"spine-player-dropdown-title\">Skins</div>\n\t\t\t\t\t<hr>\n\t\t\t\t\t<ul class=\"spine-player-list\">\n\t\t\t\t\t</ul>\n\t\t\t\t";
-                var rows = findWithClass(dropdown, "spine-player-list")[0];
-                _this.skeleton.data.skins.forEach(function (skin) {
-                    var row = document.createElement("li");
-                    row.classList.add("spine-player-list-item");
-                    if (skin.name == _this.config.skin)
-                        row.classList.add("spine-player-list-item-selected");
-                    row.innerText = skin.name;
-                    rows.appendChild(row);
-                    row.onclick = function () {
-                        removeClass(rows.children, "spine-player-list-item-selected");
-                        row.classList.add("spine-player-list-item-selected");
-                        _this.config.skin = skin.name;
-                        _this.skeleton.setSkinByName(_this.config.skin);
-                        _this.skeleton.setSlotsToSetupPose();
-                    };
-                });
-                justClicked = true;
-                window.onclick = dismissDropdown;
+            this.skinButton.onclick = function () {
+                _this.showSkinsDialog();
             };
             settingsButton.onclick = function () {
-                if (!_this.skeleton || _this.skeleton.data.animations.length == 0)
-                    return;
-                dropdown.classList.remove("spine-player-hidden");
-                dropdown.innerHTML = "\n\t\t\t\t\t<div class=\"spine-player-dropdown-title\">Debug</div>\n\t\t\t\t\t<hr>\n\t\t\t\t\t<div class=\"spine-player-list\" style=\"user-select: none; align-items: center; max-height: 90px; overflow: auto;\">\n\t\t\t\t\t</div>\n\t\t\t\t";
-                var rows = findWithClass(dropdown, "spine-player-list")[0];
-                var makeItem = function (name) {
-                    var row = document.createElement("div");
-                    row.classList.add("spine-player-list-item");
-                    if (_this.config.debug[name] == true)
-                        row.classList.add("spine-player-list-item-selected");
-                    row.innerText = name;
-                    rows.appendChild(row);
-                    row.onclick = function () {
-                        if (_this.config.debug[name]) {
-                            _this.config.debug[name] = false;
-                            row.classList.remove("spine-player-list-item-selected");
-                        }
-                        else {
-                            _this.config.debug[name] = true;
-                            row.classList.add("spine-player-list-item-selected");
-                        }
-                    };
-                };
-                Object.keys(_this.config.debug).forEach(function (name) {
-                    makeItem(name);
-                });
-                justClicked = true;
-                window.onclick = dismissDropdown;
+                _this.showSettingsDialog();
             };
             fullscreenButton.onclick = function () {
                 var doc = document;
@@ -9646,7 +9656,7 @@ var spine;
                         doc.msExitFullscreen();
                 }
                 else {
-                    var player = findWithClass(parent, "spine-player")[0];
+                    var player = dom;
                     if (player.requestFullscreen)
                         player.requestFullscreen();
                     else if (player.webkitRequestFullScreen)
@@ -9660,6 +9670,95 @@ var spine;
             window.onresize = function () {
                 _this.drawFrame(false);
             };
+            return dom;
+        };
+        SpinePlayer.prototype.showSpeedDialog = function () {
+            var _this = this;
+            var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-row\" style=\"user-select: none; align-items: center; padding: 8px;\">\n\t\t\t\t\t<div style=\"margin-right: 16px;\">Speed</div>\n\t\t\t\t\t<div class=\"spine-player-column\">\n\t\t\t\t\t\t<div class=\"spine-player-speed-slider\" style=\"margin-bottom: 4px;\"></div>\n\t\t\t\t\t\t<div class=\"spine-player-row\" style=\"justify-content: space-between;\">\n\t\t\t\t\t\t\t<div>0.1x</div>\n\t\t\t\t\t\t\t<div>1x</div>\n\t\t\t\t\t\t\t<div>2x</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t");
+            var sliderParent = findWithClass(popup.dom, "spine-player-speed-slider")[0];
+            var slider = new Slider(2);
+            sliderParent.appendChild(slider.render());
+            slider.setValue(this.speed / 2);
+            slider.change = function (percentage) {
+                _this.speed = percentage * 2;
+            };
+            popup.show();
+        };
+        SpinePlayer.prototype.showAnimationsDialog = function () {
+            var _this = this;
+            if (!this.skeleton || this.skeleton.data.animations.length == 0)
+                return;
+            var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-popup-title\">Animations</div>\n\t\t\t\t<hr>\n\t\t\t\t<ul class=\"spine-player-list\"></ul>\n\t\t\t");
+            var rows = findWithClass(popup.dom, "spine-player-list")[0];
+            this.skeleton.data.animations.forEach(function (animation) {
+                if (_this.config.animations && _this.config.animations.indexOf(animation.name) < 0) {
+                    return;
+                }
+                var row = createElement("\n\t\t\t\t\t<li class=\"spine-player-list-item selectable\">\n\t\t\t\t\t\t<div class=\"selectable-circle\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"selectable-text\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t");
+                if (animation.name == _this.config.animation)
+                    row.classList.add("selected");
+                findWithClass(row, "selectable-text")[0].innerText = animation.name;
+                rows.appendChild(row);
+                row.onclick = function () {
+                    removeClass(rows.children, "selected");
+                    row.classList.add("selected");
+                    _this.config.animation = animation.name;
+                    _this.playTime = 0;
+                    _this.animationState.setAnimation(0, _this.config.animation, true);
+                };
+            });
+            popup.show();
+        };
+        SpinePlayer.prototype.showSkinsDialog = function () {
+            var _this = this;
+            if (!this.skeleton || this.skeleton.data.animations.length == 0)
+                return;
+            var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-popup-title\">Skins</div>\n\t\t\t\t<hr>\n\t\t\t\t<ul class=\"spine-player-list\"></ul>\n\t\t\t");
+            var rows = findWithClass(popup.dom, "spine-player-list")[0];
+            this.skeleton.data.skins.forEach(function (skin) {
+                if (_this.config.skins && _this.config.skins.indexOf(skin.name) < 0) {
+                    return;
+                }
+                var row = createElement("\n\t\t\t\t\t<li class=\"spine-player-list-item selectable\">\n\t\t\t\t\t\t<div class=\"selectable-circle\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"selectable-text\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t");
+                if (skin.name == _this.config.skin)
+                    row.classList.add("selected");
+                findWithClass(row, "selectable-text")[0].innerText = skin.name;
+                rows.appendChild(row);
+                row.onclick = function () {
+                    removeClass(rows.children, "selected");
+                    row.classList.add("selected");
+                    _this.config.skin = skin.name;
+                    _this.skeleton.setSkinByName(_this.config.skin);
+                    _this.skeleton.setSlotsToSetupPose();
+                };
+            });
+            popup.show();
+        };
+        SpinePlayer.prototype.showSettingsDialog = function () {
+            var _this = this;
+            if (!this.skeleton || this.skeleton.data.animations.length == 0)
+                return;
+            var popup = new Popup(this.playerControls, "\n\t\t\t\t<div class=\"spine-player-popup-title\">Debug</div>\n\t\t\t\t<hr>\n\t\t\t\t<ul class=\"spine-player-list\">\n\t\t\t\t</li>\n\t\t\t");
+            var rows = findWithClass(popup.dom, "spine-player-list")[0];
+            var makeItem = function (label, name) {
+                var row = createElement("<li class=\"spine-player-list-item\"></li>");
+                var s = new Switch(label);
+                row.appendChild(s.render());
+                s.setEnabled(_this.config.debug[name]);
+                s.change = function (value) {
+                    _this.config.debug[name] = value;
+                };
+                rows.appendChild(row);
+            };
+            makeItem("Bones", "bones");
+            makeItem("Regions", "regions");
+            makeItem("Meshes", "meshes");
+            makeItem("Bounds", "bounds");
+            makeItem("Paths", "paths");
+            makeItem("Clipping", "clipping");
+            makeItem("Points", "points");
+            makeItem("Hulls", "hulls");
+            popup.show();
         };
         SpinePlayer.prototype.drawFrame = function (requestNextFrame) {
             var _this = this;
@@ -9681,29 +9780,52 @@ var spine;
                     var delta = this.time.delta * this.speed;
                     var animationDuration = this.animationState.getCurrent(0).animation.duration;
                     this.playTime += delta;
-                    while (this.playTime >= animationDuration) {
+                    while (this.playTime >= animationDuration && animationDuration != 0) {
                         this.playTime -= animationDuration;
                     }
                     this.playTime = Math.max(0, Math.min(this.playTime, animationDuration));
                     this.timelineSlider.setValue(this.playTime / animationDuration);
                     this.animationState.update(delta);
                     this.animationState.apply(this.skeleton);
-                    this.skeleton.updateWorldTransform();
                 }
+                this.skeleton.updateWorldTransform();
                 var viewportSize = this.scale(this.config.viewport.width, this.config.viewport.height, this.canvas.width, this.canvas.height);
                 this.sceneRenderer.camera.zoom = this.config.viewport.width / viewportSize.x;
                 this.sceneRenderer.camera.position.x = this.config.viewport.x + this.config.viewport.width / 2;
                 this.sceneRenderer.camera.position.y = this.config.viewport.y + this.config.viewport.height / 2;
                 this.sceneRenderer.begin();
+                if (this.config.backgroundImage && this.config.backgroundImage.url) {
+                    var bgImage = this.assetManager.get(this.config.backgroundImage.url);
+                    if (!this.config.backgroundImage.x) {
+                        this.sceneRenderer.drawTexture(bgImage, this.config.viewport.x, this.config.viewport.y, this.config.viewport.width, this.config.viewport.height);
+                    }
+                    else {
+                        this.sceneRenderer.drawTexture(bgImage, this.config.backgroundImage.x, this.config.backgroundImage.y, this.config.backgroundImage.width, this.config.backgroundImage.height);
+                    }
+                }
                 this.sceneRenderer.drawSkeleton(this.skeleton, this.config.premultipliedAlpha);
                 this.sceneRenderer.skeletonDebugRenderer.drawBones = this.config.debug.bones;
                 this.sceneRenderer.skeletonDebugRenderer.drawBoundingBoxes = this.config.debug.bounds;
                 this.sceneRenderer.skeletonDebugRenderer.drawClipping = this.config.debug.clipping;
-                this.sceneRenderer.skeletonDebugRenderer.drawMeshHull = this.config.debug.meshHull;
+                this.sceneRenderer.skeletonDebugRenderer.drawMeshHull = this.config.debug.hulls;
                 this.sceneRenderer.skeletonDebugRenderer.drawPaths = this.config.debug.paths;
                 this.sceneRenderer.skeletonDebugRenderer.drawRegionAttachments = this.config.debug.regions;
-                this.sceneRenderer.skeletonDebugRenderer.drawMeshTriangles = this.config.debug.triangles;
+                this.sceneRenderer.skeletonDebugRenderer.drawMeshTriangles = this.config.debug.meshes;
                 this.sceneRenderer.drawSkeletonDebug(this.skeleton, this.config.premultipliedAlpha);
+                var controlBones = this.config.controlBones;
+                var selectedBones = this.selectedBones;
+                var skeleton = this.skeleton;
+                gl.lineWidth(2);
+                for (var i = 0; i < controlBones.length; i++) {
+                    var bone = skeleton.findBone(controlBones[i]);
+                    if (!bone)
+                        continue;
+                    var colorInner = selectedBones[i] !== null ? SpinePlayer.HOVER_COLOR_INNER : SpinePlayer.NON_HOVER_COLOR_INNER;
+                    var colorOuter = selectedBones[i] !== null ? SpinePlayer.HOVER_COLOR_OUTER : SpinePlayer.NON_HOVER_COLOR_OUTER;
+                    this.sceneRenderer.circle(true, skeleton.x + bone.worldX, skeleton.y + bone.worldY, 20, colorInner);
+                    this.sceneRenderer.circle(false, skeleton.x + bone.worldX, skeleton.y + bone.worldY, 20, colorOuter);
+                }
+                gl.lineWidth(1);
                 this.sceneRenderer.end();
                 this.sceneRenderer.camera.zoom = 0;
             }
@@ -9721,20 +9843,50 @@ var spine;
             var _this = this;
             if (this.loaded)
                 return;
+            if (this.assetManager.hasErrors()) {
+                this.showError("Error: assets could not be loaded.<br><br>" + escapeHtml(JSON.stringify(this.assetManager.getErrors())));
+                return;
+            }
             var atlas = this.assetManager.get(this.config.atlasUrl);
             var jsonText = this.assetManager.get(this.config.jsonUrl);
             var json = new spine.SkeletonJson(new spine.AtlasAttachmentLoader(atlas));
-            var skeletonData = json.readSkeletonData(jsonText);
+            var skeletonData;
+            try {
+                skeletonData = json.readSkeletonData(jsonText);
+            }
+            catch (e) {
+                this.showError("Error: could not load skeleton .json.<br><br>" + escapeHtml(JSON.stringify(e)));
+                return;
+            }
             this.skeleton = new spine.Skeleton(skeletonData);
             var stateData = new spine.AnimationStateData(skeletonData);
             stateData.defaultMix = 0.2;
             this.animationState = new spine.AnimationState(stateData);
+            if (this.config.controlBones) {
+                this.config.controlBones.forEach(function (bone) {
+                    if (!skeletonData.findBone(bone)) {
+                        _this.showError("Error: control bone '" + bone + "' does not exist in skeleton.");
+                    }
+                });
+            }
             if (!this.config.skin) {
                 if (skeletonData.skins.length > 0) {
                     this.config.skin = skeletonData.skins[0].name;
                 }
             }
+            if (this.config.skins && this.config.skin.length > 0) {
+                this.config.skins.forEach(function (skin) {
+                    if (!_this.skeleton.data.findSkin(skin)) {
+                        _this.showError("Error: skin '" + skin + "' in selectable skin list does not exist in skeleton.");
+                        return;
+                    }
+                });
+            }
             if (this.config.skin) {
+                if (!this.skeleton.data.findSkin(this.config.skin)) {
+                    this.showError("Error: skin '" + this.config.skin + "' does not exist in skeleton.");
+                    return;
+                }
                 this.skeleton.setSkinByName(this.config.skin);
                 this.skeleton.setSlotsToSetupPose();
             }
@@ -9754,12 +9906,27 @@ var spine;
                 this.config.viewport.width = size.x * 1.2;
                 this.config.viewport.height = size.y * 1.2;
             }
+            if (this.config.animations && this.config.animations.length > 0) {
+                this.config.animations.forEach(function (animation) {
+                    if (!_this.skeleton.data.findAnimation(animation)) {
+                        _this.showError("Error: animation '" + animation + "' in selectable animation list does not exist in skeleton.");
+                        return;
+                    }
+                });
+                if (!this.config.animation) {
+                    this.config.animation = this.config.animations[0];
+                }
+            }
             if (!this.config.animation) {
                 if (skeletonData.animations.length > 0) {
                     this.config.animation = skeletonData.animations[0].name;
                 }
             }
             if (this.config.animation) {
+                if (!skeletonData.findAnimation(this.config.animation)) {
+                    this.showError("Error: animation '" + this.config.animation + "' does not exist in skeleton.");
+                    return;
+                }
                 this.play();
                 this.timelineSlider.change = function (percentage) {
                     _this.pause();
@@ -9771,8 +9938,106 @@ var spine;
                     _this.playTime = time;
                 };
             }
+            this.setupInput();
+            if (skeletonData.skins.length == 1)
+                this.skinButton.classList.add("spine-player-hidden");
+            if (skeletonData.animations.length == 1)
+                this.animationButton.classList.add("spine-player-hidden");
+            this.config.success(this);
             this.loaded = true;
         };
+        SpinePlayer.prototype.setupInput = function () {
+            var _this = this;
+            var controlBones = this.config.controlBones;
+            var selectedBones = this.selectedBones = new Array(this.config.controlBones.length);
+            var canvas = this.canvas;
+            var input = new spine.webgl.Input(canvas);
+            var target = null;
+            var coords = new spine.webgl.Vector3();
+            var temp = new spine.webgl.Vector3();
+            var temp2 = new spine.Vector2();
+            var skeleton = this.skeleton;
+            var renderer = this.sceneRenderer;
+            input.addListener({
+                down: function (x, y) {
+                    for (var i = 0; i < controlBones.length; i++) {
+                        var bone = skeleton.findBone(controlBones[i]);
+                        if (!bone)
+                            continue;
+                        renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.width, canvas.height);
+                        if (temp.set(skeleton.x + bone.worldX, skeleton.y + bone.worldY, 0).distance(coords) < 30) {
+                            target = bone;
+                        }
+                    }
+                    handleHover();
+                },
+                up: function (x, y) {
+                    target = null;
+                    handleHover();
+                },
+                dragged: function (x, y) {
+                    if (target != null) {
+                        renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.width, canvas.height);
+                        if (target.parent !== null) {
+                            target.parent.worldToLocal(temp2.set(coords.x - skeleton.x, coords.y - skeleton.y));
+                            target.x = temp2.x;
+                            target.y = temp2.y;
+                        }
+                        else {
+                            target.x = coords.x - skeleton.x;
+                            target.y = coords.y - skeleton.y;
+                        }
+                    }
+                    handleHover();
+                },
+                moved: function (x, y) {
+                    for (var i = 0; i < controlBones.length; i++) {
+                        var bone = skeleton.findBone(controlBones[i]);
+                        if (!bone)
+                            continue;
+                        renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.width, canvas.height);
+                        if (temp.set(skeleton.x + bone.worldX, skeleton.y + bone.worldY, 0).distance(coords) < 30) {
+                            selectedBones[i] = bone;
+                        }
+                        else {
+                            selectedBones[i] = null;
+                        }
+                    }
+                    handleHover();
+                }
+            });
+            var mouseOverChildren = false;
+            canvas.onmouseover = function (ev) {
+                mouseOverChildren = false;
+            };
+            canvas.onmouseout = function (ev) {
+                if (ev.relatedTarget == null) {
+                    mouseOverChildren = false;
+                }
+                else {
+                    mouseOverChildren = isContained(_this.dom, ev.relatedTarget);
+                }
+            };
+            var cancelId = 0;
+            var handleHover = function () {
+                if (!_this.config.showControls)
+                    return;
+                clearTimeout(cancelId);
+                _this.playerControls.classList.remove("hidden");
+                _this.playerControls.classList.add("visible");
+                var remove = function () {
+                    var popup = findWithClass(_this.dom, "spine-player-popup");
+                    if (popup.length == 0 && !mouseOverChildren) {
+                        _this.playerControls.classList.remove("visible");
+                        _this.playerControls.classList.add("hidden");
+                    }
+                    else {
+                        cancelId = setTimeout(remove, 1000);
+                    }
+                };
+                cancelId = setTimeout(remove, 1000);
+            };
+        };
         SpinePlayer.prototype.play = function () {
             this.paused = false;
             this.playButton.classList.remove("spine-player-button-icon-play");
@@ -9788,18 +10053,10 @@ var spine;
             this.playButton.classList.remove("spine-player-button-icon-pause");
             this.playButton.classList.add("spine-player-button-icon-play");
         };
-        SpinePlayer.prototype.resize = function () {
-            var canvas = this.canvas;
-            var w = canvas.clientWidth;
-            var h = canvas.clientHeight;
-            var devicePixelRatio = window.devicePixelRatio || 1;
-            if (canvas.width != Math.floor(w * devicePixelRatio) || canvas.height != Math.floor(h * devicePixelRatio)) {
-                canvas.width = Math.floor(w * devicePixelRatio);
-                canvas.height = Math.floor(h * devicePixelRatio);
-            }
-            this.context.gl.viewport(0, 0, canvas.width, canvas.height);
-            this.sceneRenderer.camera.setViewport(canvas.width, canvas.height);
-        };
+        SpinePlayer.HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.25);
+        SpinePlayer.HOVER_COLOR_OUTER = new spine.Color(1, 1, 1, 1);
+        SpinePlayer.NON_HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.5);
+        SpinePlayer.NON_HOVER_COLOR_OUTER = new spine.Color(1, 0, 0, 0.8);
         return SpinePlayer;
     }());
     spine.SpinePlayer = SpinePlayer;
@@ -9844,11 +10101,26 @@ var spine;
         findRecursive(dom, className, found);
         return found;
     }
+    function createElement(html) {
+        var dom = document.createElement("div");
+        dom.innerHTML = html;
+        return dom.children[0];
+    }
     function removeClass(elements, clazz) {
         for (var i = 0; i < elements.length; i++) {
             elements[i].classList.remove(clazz);
         }
     }
+    function escapeHtml(str) {
+        if (!str)
+            return "";
+        return str
+            .replace(/&/g, "&amp;")
+            .replace(/</g, "&lt;")
+            .replace(/>/g, "&gt;")
+            .replace(/"/g, "&#34;")
+            .replace(/'/g, "&#39;");
+    }
 })(spine || (spine = {}));
 var spine;
 (function (spine) {

文件差异内容过多而无法显示
+ 0 - 0
spine-ts/build/spine-widget.js.map


文件差异内容过多而无法显示
+ 249 - 0
spine-ts/widget/css/spine-player.css


文件差异内容过多而无法显示
+ 8 - 125
spine-ts/widget/example/player-test.html


文件差异内容过多而无法显示
+ 562 - 211
spine-ts/widget/src/Player.ts


+ 1 - 2
spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs

@@ -34,7 +34,6 @@ namespace Spine.Unity {
 	
 	[ExecuteInEditMode]
 	[AddComponentMenu("Spine/SkeletonAnimation")]
-	[HelpURL("http://esotericsoftware.com/spine-unity-documentation#Controlling-Animation")]
 	public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation, IAnimationStateComponent {
 
 		#region IAnimationStateComponent
@@ -158,7 +157,7 @@ namespace Spine.Unity {
 					if (Application.isPlaying) {
 					#endif
 
-						// Make this block not run in Unity Editor edit mode.
+						// In Unity Editor edit mode, make this block not run.
 						state.SetAnimation(0, animationObject, loop);
 
 					#if UNITY_EDITOR

+ 50 - 14
spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs

@@ -35,12 +35,16 @@ using System.Collections.Generic;
 using UnityEngine;
 
 namespace Spine.Unity {
-	/// <summary>Renders a skeleton.</summary>
+	/// <summary>Base class of animated Spine skeleton components. This component manages and renders a skeleton.</summary>
 	[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer)), DisallowMultipleComponent]
-	[HelpURL("http://esotericsoftware.com/spine-unity-documentation#Rendering")]
+	[HelpURL("http://esotericsoftware.com/spine-unity-rendering")]
 	public class SkeletonRenderer : MonoBehaviour, ISkeletonComponent, IHasSkeletonDataAsset {
 
+		public bool logErrors = false;
+
 		public delegate void SkeletonRendererDelegate (SkeletonRenderer skeletonRenderer);
+
+		/// <summary>OnRebuild is raised after the Skeleton is successfully initialized.</summary>
 		public event SkeletonRendererDelegate OnRebuild;
 
 		/// <summary> Occurs after the vertex data is populated every frame, before the vertices are pushed into the mesh.</summary>
@@ -48,34 +52,59 @@ namespace Spine.Unity {
 
 		public SkeletonDataAsset skeletonDataAsset;
 		public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } } // ISkeletonComponent
-		[SpineSkin(defaultAsEmptyString:true)]
-		public string initialSkinName;
+
+		#region Initialization settings
+		/// <summary>Skin name to use when the Skeleton is initialized.</summary>
+		[SpineSkin(defaultAsEmptyString:true)] public string initialSkinName;
+
+		/// <summary>Flip X and Y to use when the Skeleton is initialized.</summary>
 		public bool initialFlipX, initialFlipY;
+		#endregion
 
-		#region Advanced
+		#region Advanced Render Settings
 		// Submesh Separation
+		/// <summary>Slot names used to populate separatorSlots list when the Skeleton is initialized. Changing this after initialization does nothing.</summary>
 		[UnityEngine.Serialization.FormerlySerializedAs("submeshSeparators")][SerializeField][SpineSlot] protected string[] separatorSlotNames = new string[0];
+
+		/// <summary>Slots that determine where the render is split. This is used by components such as SkeletonRenderSeparator so that the skeleton can be rendered by two separate renderers on different GameObjects.</summary>
 		[System.NonSerialized] public readonly List<Slot> separatorSlots = new List<Slot>();
 
+		// Render Settings
 		[Range(-0.1f, 0f)] public float zSpacing;
+		/// <summary>Use Spine's clipping feature. If false, ClippingAttachments will be ignored.</summary>
 		public bool useClipping = true;
+
+		/// <summary>If true, triangles will not be updated. Enable this as an optimization if the skeleton does not make use of attachment swapping or hiding, or draw order keys. Otherwise, setting this to false may cause errors in rendering.</summary>
 		public bool immutableTriangles = false;
+
+		/// <summary>Multiply vertex color RGB with vertex color alpha. Set this to true if the shader used for rendering is a premultiplied alpha shader. Setting this to false disables single-batch additive slots.</summary>
 		public bool pmaVertexColors = true;
+
 		/// <summary>Clears the state of the render and skeleton when this component or its GameObject is disabled. This prevents previous state from being retained when it is enabled again. When pooling your skeleton, setting this to true can be helpful.</summary>
 		public bool clearStateOnDisable = false;
+
+		/// <summary>If true, second colors on slots will be added to the output Mesh as UV2 and UV3. A special "tint black" shader that interprets UV2 and UV3 as black point colors is required to render this properly.</summary>
 		public bool tintBlack = false;
+
+		/// <summary>If true, the renderer assumes the skeleton only requires one Material and one submesh to render. This allows the MeshGenerator to skip checking for changes in Materials. Enable this as an optimization if the skeleton only uses one Material.</summary>
+		/// <remarks>This disables SkeletonRenderSeparator functionality.</remarks>
 		public bool singleSubmesh = false;
 
-		[UnityEngine.Serialization.FormerlySerializedAs("calculateNormals")]
-		public bool addNormals = false;
-		public bool calculateTangents = false;
+		/// <summary>If true, the mesh generator adds normals to the output mesh. For better performance and reduced memory requirements, use a shader that assumes the desired normal.</summary>
+		[UnityEngine.Serialization.FormerlySerializedAs("calculateNormals")] public bool addNormals = false;
 
-		public bool logErrors = false;
+		/// <summary>If true, tangents are calculated every frame and added to the Mesh. Enable this when using a shader that uses lighting that requires tangents.</summary>
+		public bool calculateTangents = false;
+		#endregion
 
+		#region Overrides
 		#if SPINE_OPTIONAL_RENDEROVERRIDE
+		// These are API for anything that wants to take over rendering for a SkeletonRenderer.
 		public bool disableRenderingOnOverride = true;
 		public delegate void InstructionDelegate (SkeletonRendererInstruction instruction);
 		event InstructionDelegate generateMeshOverride;
+
+		/// <summary>Allows separate code to take over rendering for this SkeletonRenderer component. The subscriber is passed a SkeletonRendererInstruction argument to determine how to render a skeleton.</summary>
 		public event InstructionDelegate GenerateMeshOverride {
 			add {
 				generateMeshOverride += value;
@@ -96,17 +125,27 @@ namespace Spine.Unity {
 
 		#if SPINE_OPTIONAL_MATERIALOVERRIDE
 		[System.NonSerialized] readonly Dictionary<Material, Material> customMaterialOverride = new Dictionary<Material, Material>();
+		/// <summary>Use this Dictionary to override a Material with a different Material.</summary>
 		public Dictionary<Material, Material> CustomMaterialOverride { get { return customMaterialOverride; } }
 		#endif
 
-		// Custom Slot Material
 		[System.NonSerialized] readonly Dictionary<Slot, Material> customSlotMaterials = new Dictionary<Slot, Material>();
+		/// <summary>Use this Dictionary to use a different Material to render specific Slots.</summary>
 		public Dictionary<Slot, Material> CustomSlotMaterials { get { return customSlotMaterials; } }
 		#endregion
 
+		#region Mesh Generator
+		[System.NonSerialized] readonly SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction();
+		readonly MeshGenerator meshGenerator = new MeshGenerator();
+		[System.NonSerialized] readonly MeshRendererBuffers rendererBuffers = new MeshRendererBuffers();
+		#endregion
+
+		#region Cached component references
 		MeshRenderer meshRenderer;
 		MeshFilter meshFilter;
+		#endregion
 
+		#region Skeleton
 		[System.NonSerialized] public bool valid;
 		[System.NonSerialized] public Skeleton skeleton;
 		public Skeleton Skeleton {
@@ -115,10 +154,7 @@ namespace Spine.Unity {
 				return skeleton;
 			}
 		}
-			
-		[System.NonSerialized] readonly SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction();
-		readonly MeshGenerator meshGenerator = new MeshGenerator();
-		[System.NonSerialized] readonly MeshRendererBuffers rendererBuffers = new MeshRendererBuffers();
+		#endregion
 
 		#region Runtime Instantiation
 		public static T NewSpineGameObject<T> (SkeletonDataAsset skeletonDataAsset) where T : SkeletonRenderer {

+ 13 - 6
spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs

@@ -84,7 +84,6 @@ namespace Spine.Unity {
 	}
 
 	public delegate void MeshGeneratorDelegate (MeshGeneratorBuffers buffers);
-
 	public struct MeshGeneratorBuffers {
 		/// <summary>The vertex count that will actually be used for the mesh. The Lengths of the buffer arrays may be larger than this number.</summary>
 		public int vertexCount;
@@ -102,6 +101,7 @@ namespace Spine.Unity {
 		public MeshGenerator meshGenerator;
 	}
 
+	/// <summary>Holds several methods to prepare and generate a UnityEngine mesh based on a skeleton. Contains buffers needed to perform the operation, and serializes settings for mesh generation.</summary>
 	[System.Serializable]
 	public class MeshGenerator {
 		public Settings settings = Settings.Default;
@@ -152,6 +152,7 @@ namespace Spine.Unity {
 		[NonSerialized] int[] regionTriangles = { 0, 1, 2, 2, 3, 0 };
 
 		#region Optional Buffers
+		// These optional buffers are lazy-instantiated when the feature is used.
 		[NonSerialized] Vector3[] normals;
 		[NonSerialized] Vector4[] tangents;
 		[NonSerialized] Vector2[] tempTanBuffer;
@@ -161,6 +162,7 @@ namespace Spine.Unity {
 
 		public int VertexCount { get { return vertexBuffer.Count; } }
 
+		/// <summary>A set of mesh arrays whose values are modifiable by the user. Modify these values before they are passed to the UnityEngine mesh object in order to see the effect.</summary>
 		public MeshGeneratorBuffers Buffers {
 			get {
 				return new MeshGeneratorBuffers {
@@ -1093,6 +1095,7 @@ namespace Spine.Unity {
 			}
 		}
 
+		/// <summary>Trims internal buffers to reduce the resulting mesh data stream size.</summary>
 		public void TrimExcess () {
 			vertexBuffer.TrimExcess();
 			uvBuffer.TrimExcess();
@@ -1201,8 +1204,7 @@ namespace Spine.Unity {
 		static List<Color32> AttachmentColors32 = new List<Color32>();
 		static List<int> AttachmentIndices = new List<int>();
 
-		/// <summary>
-		/// Fills mesh vertex data to render a RegionAttachment.</summary>
+		/// <summary>Fills mesh vertex data to render a RegionAttachment.</summary>
 		public static void FillMeshLocal (Mesh mesh, RegionAttachment regionAttachment) {
 			if (mesh == null) return;
 			if (regionAttachment == null) return;
@@ -1308,11 +1310,10 @@ namespace Spine.Unity {
 			AttachmentColors32.Clear();
 			AttachmentIndices.Clear();
 		}
-
-		
 		#endregion
 	}
 
+	/// <summary>A double-buffered Mesh, and a shared material array, bundled for use by Spine components that need to push a Mesh and materials to a Unity MeshRenderer and MeshFilter.</summary>
 	public class MeshRendererBuffers : IDisposable {
 		DoubleBuffered<SmartMesh> doubleBufferedMesh;
 		internal readonly ExposedList<Material> submeshMaterials = new ExposedList<Material>();
@@ -1328,6 +1329,8 @@ namespace Spine.Unity {
 			}
 		}
 
+		/// <summary>Returns a sharedMaterials array for use on a MeshRenderer.</summary>
+		/// <returns></returns>
 		public Material[] GetUpdatedSharedMaterialsArray () {
 			if (submeshMaterials.Count == sharedMaterials.Length)
 				submeshMaterials.CopyTo(sharedMaterials);
@@ -1337,6 +1340,7 @@ namespace Spine.Unity {
 			return sharedMaterials;
 		}
 
+		/// <summary>Returns true if the materials were modified since the buffers were last updated.</summary>
 		public bool MaterialsChangedInLastUpdate () {
 			int newSubmeshMaterials = submeshMaterials.Count;
 			var sharedMaterials = this.sharedMaterials;
@@ -1349,6 +1353,7 @@ namespace Spine.Unity {
 			return false;
 		}
 
+		/// <summary>Updates the internal shared materials array with the given instruction list.</summary>
 		public void UpdateSharedMaterials (ExposedList<SubmeshInstruction> instructions) {
 			int newSize = instructions.Count;
 			{ //submeshMaterials.Resize(instructions.Count);
@@ -1405,10 +1410,11 @@ namespace Spine.Unity {
 		}
 	}
 
+	/// <summary>Instructions used by a SkeletonRenderer to render a mesh.</summary>
 	public class SkeletonRendererInstruction {
-		public bool immutableTriangles;
 		public readonly ExposedList<SubmeshInstruction> submeshInstructions = new ExposedList<SubmeshInstruction>();
 
+		public bool immutableTriangles;
 		#if SPINE_TRIANGLECHECK
 		public bool hasActiveClipping;
 		public int rawVertexCount = -1;
@@ -1540,4 +1546,5 @@ namespace Spine.Unity {
 		}
 	}
 
+
 }

+ 5 - 11
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs

@@ -823,18 +823,12 @@ namespace Spine.Unity.Modules.AttachmentTools {
 		public static void SetAttachment (this Skin skin, int slotIndex, string keyName, Attachment attachment) {
 			skin.AddAttachment(slotIndex, keyName, attachment);
 		}
-
-		/// <summary>Removes the attachment. Returns true if the element is successfully found and removed; otherwise, false.</summary>
-		public static bool RemoveAttachment (this Skin skin, string slotName, string keyName, Skeleton skeleton) {
-			int slotIndex = skeleton.FindSlotIndex(slotName);
-			if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null.");
+		
+		public static void RemoveAttachment (this Skin skin, string slotName, string keyName, SkeletonData skeletonData) {
+			int slotIndex = skeletonData.FindSlotIndex(slotName);
+			if (skeletonData == null) throw new System.ArgumentNullException("skeletonData", "skeletonData cannot be null.");
 			if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName");
-			return skin.RemoveAttachment(slotIndex, keyName);
-		}
-
-		/// <summary>Removes the attachment. Returns true if the element is successfully found and removed; otherwise, false.</summary>
-		public static bool RemoveAttachment (this Skin skin, int slotIndex, string keyName) {
-			return skin.Attachments.Remove(new Skin.AttachmentKeyTuple(slotIndex, keyName));
+			skin.RemoveAttachment(slotIndex, keyName);
 		}
 
 		public static void Clear (this Skin skin) {

+ 9 - 4
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs

@@ -106,16 +106,21 @@ namespace Spine.Unity {
 		#endregion
 
 		#region Runtime Instantiation
-		public static SkeletonGraphic NewSkeletonGraphicGameObject (SkeletonDataAsset skeletonDataAsset, Transform parent) {
-			SkeletonGraphic sg = SkeletonGraphic.AddSkeletonGraphicComponent(new GameObject("New Spine GameObject"), skeletonDataAsset);
+		/// <summary>Create a new GameObject with a SkeletonGraphic component.</summary>
+		/// <param name="material">Material for the canvas renderer to use. Usually, the default SkeletonGraphic material will work.</param>
+		public static SkeletonGraphic NewSkeletonGraphicGameObject (SkeletonDataAsset skeletonDataAsset, Transform parent, Material material) {
+			var sg = SkeletonGraphic.AddSkeletonGraphicComponent(new GameObject("New Spine GameObject"), skeletonDataAsset, material);
 			if (parent != null) sg.transform.SetParent(parent, false);
 			return sg;
 		}
 
-		public static SkeletonGraphic AddSkeletonGraphicComponent (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) {
+		/// <summary>Add a SkeletonGraphic component to a GameObject.</summary>
+		/// <param name="material">Material for the canvas renderer to use. Usually, the default SkeletonGraphic material will work.</param>
+		public static SkeletonGraphic AddSkeletonGraphicComponent (GameObject gameObject, SkeletonDataAsset skeletonDataAsset, Material material) {
 			var c = gameObject.AddComponent<SkeletonGraphic>();
 			if (skeletonDataAsset != null) {
-				c.skeletonDataAsset = skeletonDataAsset;				
+				c.material = material;
+				c.skeletonDataAsset = skeletonDataAsset;
 				c.Initialize(false);
 			}
 			return c;

+ 12 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs

@@ -37,7 +37,7 @@ using Spine.Unity;
 namespace Spine.Unity.Modules {
 	
 	[ExecuteInEditMode]
-	[HelpURL("https://github.com/pharan/spine-unity-docs/blob/master/SkeletonRenderSeparator.md")]
+	[HelpURL("http://esotericsoftware.com/spine-unity-skeletonrenderseparator")]
 	public class SkeletonRenderSeparator : MonoBehaviour {
 		public const int DefaultSortingOrderIncrement = 5;
 
@@ -53,7 +53,8 @@ namespace Spine.Unity.Modules {
 				#endif
 				
 				skeletonRenderer = value;
-				this.enabled = false; // Disable if nulled.
+				if (value == null)
+					this.enabled = false;
 			}
 		}
 
@@ -105,6 +106,15 @@ namespace Spine.Unity.Modules {
 				componentRenderers.Add(spr);
 			}
 
+			#if UNITY_EDITOR
+			// Make sure editor updates properly in edit mode.
+			if (!Application.isPlaying) {
+				skeletonRenderer.enabled = false;
+				skeletonRenderer.enabled = true;
+				skeletonRenderer.LateUpdate();
+			}
+			#endif
+
 			return srs;
 		}
 
@@ -167,9 +177,7 @@ namespace Spine.Unity.Modules {
 			skeletonRenderer.GenerateMeshOverride -= HandleRender;
 			#endif
 
-			#if UNITY_EDITOR
 			skeletonRenderer.LateUpdate();
-			#endif
 
 			foreach (var s in partsRenderers)
 				s.ClearMesh();		
@@ -189,7 +197,6 @@ namespace Spine.Unity.Modules {
 				calculateTangents = skeletonRenderer.calculateTangents,
 				immutableTriangles = false, // parts cannot do immutable triangles.
 				pmaVertexColors = skeletonRenderer.pmaVertexColors,
-				//renderMeshes = skeletonRenderer.renderMeshes,
 				tintBlack = skeletonRenderer.tintBlack,
 				useClipping = true,
 				zSpacing = skeletonRenderer.zSpacing

+ 5 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs

@@ -136,6 +136,11 @@ namespace Spine.Unity {
 		bool hasConstraints;
 		bool needToReprocessBones;
 
+		public void ResubscribeEvents () {
+			OnDisable();
+			OnEnable();
+		}
+		
 		void OnEnable () {
 			if (skeletonRenderer == null) {
 				skeletonRenderer = GetComponent<SkeletonRenderer>();

+ 15 - 14
spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs

@@ -141,23 +141,24 @@ namespace Spine.Unity {
 						// Use Applied transform values (ax, ay, AppliedRotation, ascale) if world values were modified by constraints.
 						if (!bone.appliedValid) {
 							bone.UpdateAppliedTransform();
-							if (position)
-								thisTransform.localPosition = new Vector3(bone.ax, bone.ay, 0);
-
-							if (rotation) {
-								if (bone.data.transformMode.InheritsRotation()) {
-									thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation);
-								} else {
-									Vector3 euler = skeletonTransform.rotation.eulerAngles;
-									thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
-								}
-							}
+						}
+
+						if (position)
+							thisTransform.localPosition = new Vector3(bone.ax, bone.ay, 0);
 
-							if (scale) {
-								thisTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f);
-								incompatibleTransformMode = BoneTransformModeIncompatible(bone);
+						if (rotation) {
+							if (bone.data.transformMode.InheritsRotation()) {
+								thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation);
+							} else {
+								Vector3 euler = skeletonTransform.rotation.eulerAngles;
+								thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
 							}
 						}
+
+						if (scale) {
+							thisTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f);
+							incompatibleTransformMode = BoneTransformModeIncompatible(bone);
+						}
 						break;
 				}
 				

部分文件因为文件数量过多而无法显示