[ts][player] Added controllable bones to player.

This commit is contained in:
badlogic 2018-11-08 16:00:23 +01:00
parent fe44bece46
commit 49ba1d2bd9
5 changed files with 11940 additions and 11812 deletions

View File

@ -16,11 +16,11 @@ declare module spine {
setup = 0, setup = 0,
first = 1, first = 1,
replace = 2, replace = 2,
add = 3, add = 3
} }
enum MixDirection { enum MixDirection {
in = 0, in = 0,
out = 1, out = 1
} }
enum TimelineType { enum TimelineType {
rotate = 0, rotate = 0,
@ -37,7 +37,7 @@ declare module spine {
pathConstraintPosition = 11, pathConstraintPosition = 11,
pathConstraintSpacing = 12, pathConstraintSpacing = 12,
pathConstraintMix = 13, pathConstraintMix = 13,
twoColor = 14, twoColor = 14
} }
abstract class CurveTimeline implements Timeline { abstract class CurveTimeline implements Timeline {
static LINEAR: number; static LINEAR: number;
@ -341,7 +341,7 @@ declare module spine {
end = 2, end = 2,
dispose = 3, dispose = 3,
complete = 4, complete = 4,
event = 5, event = 5
} }
interface AnimationStateListener2 { interface AnimationStateListener2 {
start(entry: TrackEntry): void; start(entry: TrackEntry): void;
@ -380,8 +380,8 @@ declare module spine {
private toLoad; private toLoad;
private loaded; private loaded;
constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string); constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
private static downloadText(url, success, error); private static downloadText;
private static downloadBinary(url, success, error); private static downloadBinary;
loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void; 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; 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; 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, Normal = 0,
Additive = 1, Additive = 1,
Multiply = 2, Multiply = 2,
Screen = 3, Screen = 3
} }
} }
declare module spine { declare module spine {
@ -483,7 +483,7 @@ declare module spine {
OnlyTranslation = 1, OnlyTranslation = 1,
NoRotationOrReflection = 2, NoRotationOrReflection = 2,
NoScale = 3, NoScale = 3,
NoScaleOrReflection = 4, NoScaleOrReflection = 4
} }
} }
declare module spine { declare module spine {
@ -593,17 +593,17 @@ declare module spine {
} }
enum PositionMode { enum PositionMode {
Fixed = 0, Fixed = 0,
Percent = 1, Percent = 1
} }
enum SpacingMode { enum SpacingMode {
Length = 0, Length = 0,
Fixed = 1, Fixed = 1,
Percent = 2, Percent = 2
} }
enum RotateMode { enum RotateMode {
Tangent = 0, Tangent = 0,
Chain = 1, Chain = 1,
ChainScale = 2, ChainScale = 2
} }
} }
declare module spine { declare module spine {
@ -614,12 +614,12 @@ declare module spine {
private rawAssets; private rawAssets;
private errors; private errors;
constructor(pathPrefix?: string); constructor(pathPrefix?: string);
private queueAsset(clientId, textureLoader, path); private queueAsset;
loadText(clientId: string, path: string): void; loadText(clientId: string, path: string): void;
loadJson(clientId: string, path: string): void; loadJson(clientId: string, path: string): void;
loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void; loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
get(clientId: string, path: string): any; get(clientId: string, path: string): any;
private updateClientAssets(clientAssets); private updateClientAssets;
isLoadingComplete(clientId: string): boolean; isLoadingComplete(clientId: string): boolean;
dispose(): void; dispose(): void;
hasErrors(): boolean; hasErrors(): boolean;
@ -823,12 +823,12 @@ declare module spine {
MipMapNearestNearest = 9984, MipMapNearestNearest = 9984,
MipMapLinearNearest = 9985, MipMapLinearNearest = 9985,
MipMapNearestLinear = 9986, MipMapNearestLinear = 9986,
MipMapLinearLinear = 9987, MipMapLinearLinear = 9987
} }
enum TextureWrap { enum TextureWrap {
MirroredRepeat = 33648, MirroredRepeat = 33648,
ClampToEdge = 33071, ClampToEdge = 33071,
Repeat = 10497, Repeat = 10497
} }
class TextureRegion { class TextureRegion {
renderObject: any; renderObject: any;
@ -855,7 +855,7 @@ declare module spine {
pages: TextureAtlasPage[]; pages: TextureAtlasPage[];
regions: TextureAtlasRegion[]; regions: TextureAtlasRegion[];
constructor(atlasText: string, textureLoader: (path: string) => any); constructor(atlasText: string, textureLoader: (path: string) => any);
private load(atlasText, textureLoader); private load;
findRegion(name: string): TextureAtlasRegion; findRegion(name: string): TextureAtlasRegion;
dispose(): void; dispose(): void;
} }
@ -931,9 +931,9 @@ declare module spine {
private polygonIndicesPool; private polygonIndicesPool;
triangulate(verticesArray: ArrayLike<number>): Array<number>; triangulate(verticesArray: ArrayLike<number>): Array<number>;
decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>; decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
private static isConcave(index, vertexCount, vertices, indices); private static isConcave;
private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y); private static positiveArea;
private static winding(p1x, p1y, p2x, p2y, p3x, p3y); private static winding;
} }
} }
declare module spine { declare module spine {
@ -1105,7 +1105,7 @@ declare module spine {
Mesh = 2, Mesh = 2,
LinkedMesh = 3, LinkedMesh = 3,
Path = 4, Path = 4,
Point = 5, Point = 5
} }
} }
declare module spine { declare module spine {
@ -1299,7 +1299,7 @@ declare module spine.webgl {
touchesPool: Pool<Touch>; touchesPool: Pool<Touch>;
private listeners; private listeners;
constructor(element: HTMLElement); constructor(element: HTMLElement);
private setupCallbacks(element); private setupCallbacks;
addListener(listener: InputListener): void; addListener(listener: InputListener): void;
removeListener(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; drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
bind(shader: Shader): void; bind(shader: Shader): void;
unbind(shader: Shader): void; unbind(shader: Shader): void;
private update(); private update;
restore(): void; restore(): void;
dispose(): void; dispose(): void;
} }
@ -1434,7 +1434,7 @@ declare module spine.webgl {
constructor(); constructor();
} }
enum VertexAttributeType { enum VertexAttributeType {
Float = 0, Float = 0
} }
} }
declare module spine.webgl { declare module spine.webgl {
@ -1453,7 +1453,7 @@ declare module spine.webgl {
begin(shader: Shader): void; begin(shader: Shader): void;
setBlendMode(srcBlend: number, dstBlend: number): void; setBlendMode(srcBlend: number, dstBlend: number): void;
draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void; draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
private flush(); private flush;
end(): void; end(): void;
getDrawCalls(): number; getDrawCalls(): number;
dispose(): void; 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; curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
end(): void; end(): void;
resize(resizeMode: ResizeMode): void; resize(resizeMode: ResizeMode): void;
private enableRenderer(renderer); private enableRenderer;
dispose(): void; dispose(): void;
} }
enum ResizeMode { enum ResizeMode {
Stretch = 0, Stretch = 0,
Expand = 1, Expand = 1,
Fit = 2, Fit = 2
} }
} }
declare module spine.webgl { declare module spine.webgl {
@ -1527,9 +1527,9 @@ declare module spine.webgl {
getVertexShaderSource(): string; getVertexShaderSource(): string;
getFragmentSource(): string; getFragmentSource(): string;
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, vertexShader: string, fragmentShader: string); constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, vertexShader: string, fragmentShader: string);
private compile(); private compile;
private compileShader(type, source); private compileShader;
private compileProgram(vs, fs); private compileProgram;
restore(): void; restore(): void;
bind(): void; bind(): void;
unbind(): void; unbind(): void;
@ -1576,16 +1576,16 @@ declare module spine.webgl {
polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void; 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; 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; 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; end(): void;
private flush(); private flush;
private check(shapeType, numVertices); private check;
dispose(): void; dispose(): void;
} }
enum ShapeType { enum ShapeType {
Point = 0, Point = 0,
Line = 1, Line = 1,
Filled = 4, Filled = 4
} }
} }
declare module spine.webgl { declare module spine.webgl {
@ -1716,11 +1716,16 @@ declare module spine {
height: number; height: number;
}; };
premultipliedAlpha: boolean; premultipliedAlpha: boolean;
controlBones: string[];
success: (widget: SpineWidget) => void; success: (widget: SpineWidget) => void;
error: (widget: SpineWidget, msg: string) => void; error: (widget: SpineWidget, msg: string) => void;
} }
class SpinePlayer { class SpinePlayer {
private config; 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 sceneRenderer;
private dom; private dom;
private playerControls; private playerControls;
@ -1737,6 +1742,7 @@ declare module spine {
private paused; private paused;
private playTime; private playTime;
private speed; private speed;
private selectedBones;
constructor(parent: HTMLElement, config: SpinePlayerConfig); constructor(parent: HTMLElement, config: SpinePlayerConfig);
validateConfig(config: SpinePlayerConfig): SpinePlayerConfig; validateConfig(config: SpinePlayerConfig): SpinePlayerConfig;
render(): HTMLElement; render(): HTMLElement;
@ -1747,9 +1753,9 @@ declare module spine {
drawFrame(requestNextFrame?: boolean): void; drawFrame(requestNextFrame?: boolean): void;
scale(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): Vector2; scale(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): Vector2;
loadSkeleton(): void; loadSkeleton(): void;
private play(); setupInput(): void;
private pause(); private play;
private resize(); private pause;
} }
} }
declare module spine { declare module spine {
@ -1773,10 +1779,10 @@ declare module spine {
private loaded; private loaded;
private bounds; private bounds;
constructor(element: HTMLElement | string, config: SpineWidgetConfig); constructor(element: HTMLElement | string, config: SpineWidgetConfig);
private validateConfig(config); private validateConfig;
private load(); private load;
private render(); private render;
private resize(); private resize;
pause(): void; pause(): void;
play(): void; play(): void;
isPlaying(): boolean; isPlaying(): boolean;
@ -1784,7 +1790,7 @@ declare module spine {
static loadWidgets(): void; static loadWidgets(): void;
static loadWidget(widget: HTMLElement): void; static loadWidget(widget: HTMLElement): void;
static pageLoaded: boolean; static pageLoaded: boolean;
private static ready(); private static ready;
static setupDOMListener(): void; static setupDOMListener(): void;
} }
class SpineWidgetConfig { class SpineWidgetConfig {

View File

@ -1,7 +1,10 @@
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __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]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -9561,6 +9564,8 @@ var spine;
if (config.skins.indexOf(config.skin) < 0) if (config.skins.indexOf(config.skin) < 0)
throw new Error("Default skin " + config.skin + " is not contained in the list of selectable skins."); throw new Error("Default skin " + config.skin + " is not contained in the list of selectable skins.");
} }
if (!config.controlBones)
config.controlBones = [];
return config; return config;
}; };
SpinePlayer.prototype.render = function () { SpinePlayer.prototype.render = function () {
@ -9743,7 +9748,7 @@ var spine;
var delta = this.time.delta * this.speed; var delta = this.time.delta * this.speed;
var animationDuration = this.animationState.getCurrent(0).animation.duration; var animationDuration = this.animationState.getCurrent(0).animation.duration;
this.playTime += delta; this.playTime += delta;
while (this.playTime >= animationDuration) { while (this.playTime >= animationDuration && animationDuration != 0) {
this.playTime -= animationDuration; this.playTime -= animationDuration;
} }
this.playTime = Math.max(0, Math.min(this.playTime, animationDuration)); this.playTime = Math.max(0, Math.min(this.playTime, animationDuration));
@ -9775,6 +9780,20 @@ var spine;
this.sceneRenderer.skeletonDebugRenderer.drawRegionAttachments = this.config.debug.regions; this.sceneRenderer.skeletonDebugRenderer.drawRegionAttachments = this.config.debug.regions;
this.sceneRenderer.skeletonDebugRenderer.drawMeshTriangles = this.config.debug.meshes; this.sceneRenderer.skeletonDebugRenderer.drawMeshTriangles = this.config.debug.meshes;
this.sceneRenderer.drawSkeletonDebug(this.skeleton, this.config.premultipliedAlpha); 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.end();
this.sceneRenderer.camera.zoom = 0; this.sceneRenderer.camera.zoom = 0;
} }
@ -9842,8 +9861,65 @@ var spine;
_this.playTime = time; _this.playTime = time;
}; };
} }
this.setupInput();
this.loaded = true; 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 () { SpinePlayer.prototype.play = function () {
this.paused = false; this.paused = false;
this.playButton.classList.remove("spine-player-button-icon-play"); this.playButton.classList.remove("spine-player-button-icon-play");
@ -9859,18 +9935,10 @@ var spine;
this.playButton.classList.remove("spine-player-button-icon-pause"); this.playButton.classList.remove("spine-player-button-icon-pause");
this.playButton.classList.add("spine-player-button-icon-play"); this.playButton.classList.add("spine-player-button-icon-play");
}; };
SpinePlayer.prototype.resize = function () { SpinePlayer.HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.25);
var canvas = this.canvas; SpinePlayer.HOVER_COLOR_OUTER = new spine.Color(1, 1, 1, 1);
var w = canvas.clientWidth; SpinePlayer.NON_HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.5);
var h = canvas.clientHeight; SpinePlayer.NON_HOVER_COLOR_OUTER = new spine.Color(1, 0, 0, 0.8);
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);
};
return SpinePlayer; return SpinePlayer;
}()); }());
spine.SpinePlayer = SpinePlayer; spine.SpinePlayer = SpinePlayer;

File diff suppressed because one or more lines are too long

View File

@ -277,25 +277,10 @@ body {
</body> </body>
<script> <script>
new spine.SpinePlayer(document.getElementById("container"), { new spine.SpinePlayer(document.getElementById("container"), {
jsonUrl: "assets/raptor-pro.json", jsonUrl: "assets/spineboy-pro.json",
atlasUrl: "assets/raptor.atlas", atlasUrl: "assets/spineboy.atlas",
animation: "walk", controlBones: ["root"],
animations: ["walk", "roar", "jump"], backgroundColor: "#cccccc"
skin: "default",
skins: ["default"],
backgroundColor: "#ff00ff",
backgroundImage: {
url: "assets/spineboy.png",
x: 0,
y: 0,
width: 300,
height: 200
},
debug: {
bones: true,
regions: true,
meshes: true,
}
}); });
</script> </script>
</body> </body>

View File

@ -62,6 +62,7 @@
height: number height: number
} }
premultipliedAlpha: boolean premultipliedAlpha: boolean
controlBones: string[]
success: (widget: SpineWidget) => void success: (widget: SpineWidget) => void
error: (widget: SpineWidget, msg: string) => void error: (widget: SpineWidget, msg: string) => void
} }
@ -181,6 +182,11 @@
} }
export class SpinePlayer { export class SpinePlayer {
static HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.25);
static HOVER_COLOR_OUTER = new spine.Color(1, 1, 1, 1);
static NON_HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.5);
static NON_HOVER_COLOR_OUTER = new spine.Color(1, 0, 0, 0.8);
private sceneRenderer: spine.webgl.SceneRenderer; private sceneRenderer: spine.webgl.SceneRenderer;
private dom: HTMLElement; private dom: HTMLElement;
private playerControls: HTMLElement; private playerControls: HTMLElement;
@ -200,6 +206,8 @@
private playTime = 0; private playTime = 0;
private speed = 1; private speed = 1;
private selectedBones: Bone[];
constructor(parent: HTMLElement, private config: SpinePlayerConfig) { constructor(parent: HTMLElement, private config: SpinePlayerConfig) {
this.config = this.validateConfig(config); this.config = this.validateConfig(config);
parent.appendChild(this.render()); parent.appendChild(this.render());
@ -241,6 +249,7 @@
if (config.skins.indexOf(config.skin) < 0) throw new Error("Default skin " + config.skin + " is not contained in the list of selectable skins."); if (config.skins.indexOf(config.skin) < 0) throw new Error("Default skin " + config.skin + " is not contained in the list of selectable skins.");
} }
if (!config.controlBones) config.controlBones = [];
return config; return config;
} }
@ -338,6 +347,8 @@
this.drawFrame(false); this.drawFrame(false);
} }
// Setup input handler for control bones and pan/zoom
return dom; return dom;
} }
@ -504,7 +515,7 @@
let animationDuration = this.animationState.getCurrent(0).animation.duration; let animationDuration = this.animationState.getCurrent(0).animation.duration;
this.playTime += delta; this.playTime += delta;
while (this.playTime >= animationDuration) { while (this.playTime >= animationDuration && animationDuration != 0) {
this.playTime -= animationDuration; this.playTime -= animationDuration;
} }
this.playTime = Math.max(0, Math.min(this.playTime, animationDuration)); this.playTime = Math.max(0, Math.min(this.playTime, animationDuration));
@ -544,6 +555,21 @@
this.sceneRenderer.skeletonDebugRenderer.drawMeshTriangles = this.config.debug.meshes; this.sceneRenderer.skeletonDebugRenderer.drawMeshTriangles = this.config.debug.meshes;
this.sceneRenderer.drawSkeletonDebug(this.skeleton, this.config.premultipliedAlpha); this.sceneRenderer.drawSkeletonDebug(this.skeleton, this.config.premultipliedAlpha);
// Render the selected bones
let controlBones = this.config.controlBones;
let selectedBones = this.selectedBones;
let 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.end();
this.sceneRenderer.camera.zoom = 0; this.sceneRenderer.camera.zoom = 0;
@ -608,6 +634,7 @@
this.config.animation = skeletonData.animations[0].name; this.config.animation = skeletonData.animations[0].name;
} }
} }
if(this.config.animation) { if(this.config.animation) {
this.play() this.play()
this.timelineSlider.change = (percentage) => { this.timelineSlider.change = (percentage) => {
@ -621,9 +648,65 @@
} }
} }
// Setup the input processor and controllable bones
this.setupInput();
this.loaded = true; this.loaded = true;
} }
setupInput () {
let controlBones = this.config.controlBones;
let selectedBones = this.selectedBones = new Array<Bone>(this.config.controlBones.length);
let canvas = this.canvas;
let input = new spine.webgl.Input(canvas);
var target:Bone = null;
let coords = new spine.webgl.Vector3();
let temp = new spine.webgl.Vector3();
let temp2 = new spine.Vector2();
let skeleton = this.skeleton
let renderer = this.sceneRenderer;
input.addListener({
down: (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: (x, y) => {
target = null;
},
dragged: (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: (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;
}
}
}
});
}
private play () { private play () {
this.paused = false; this.paused = false;
this.playButton.classList.remove("spine-player-button-icon-play"); this.playButton.classList.remove("spine-player-button-icon-play");
@ -641,20 +724,6 @@
this.playButton.classList.remove("spine-player-button-icon-pause"); this.playButton.classList.remove("spine-player-button-icon-pause");
this.playButton.classList.add("spine-player-button-icon-play"); this.playButton.classList.add("spine-player-button-icon-play");
} }
private resize () {
let canvas = this.canvas;
let w = canvas.clientWidth;
let 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);
}
} }
function isContained(dom: HTMLElement, needle: HTMLElement): boolean { function isContained(dom: HTMLElement, needle: HTMLElement): boolean {