mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 15:24:55 +08:00
Merge branch '3.7-beta' into 3.7-beta-cpp
This commit is contained in:
commit
7bea40c81a
8
spine-ts/build/spine-all.d.ts
vendored
8
spine-ts/build/spine-all.d.ts
vendored
@ -1841,10 +1841,10 @@ declare module spine {
|
||||
validateConfig(config: SpinePlayerConfig): SpinePlayerConfig;
|
||||
showError(error: string): void;
|
||||
render(): HTMLElement;
|
||||
showSpeedDialog(): void;
|
||||
showAnimationsDialog(): void;
|
||||
showSkinsDialog(): void;
|
||||
showSettingsDialog(): void;
|
||||
showSpeedDialog(speedButton: HTMLElement): void;
|
||||
showAnimationsDialog(animationsButton: HTMLElement): void;
|
||||
showSkinsDialog(skinButton: HTMLElement): void;
|
||||
showSettingsDialog(settingsButton: HTMLElement): void;
|
||||
drawFrame(requestNextFrame?: boolean): void;
|
||||
scale(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): Vector2;
|
||||
loadSkeleton(): void;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
32
spine-ts/build/spine-widget.d.ts
vendored
32
spine-ts/build/spine-widget.d.ts
vendored
@ -1683,6 +1683,16 @@ declare module spine.webgl {
|
||||
}
|
||||
}
|
||||
declare module spine {
|
||||
interface Viewport {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
padLeft: string | number;
|
||||
padRight: string | number;
|
||||
padTop: string | number;
|
||||
padBottom: string | number;
|
||||
}
|
||||
interface SpinePlayerConfig {
|
||||
jsonUrl: string;
|
||||
atlasUrl: string;
|
||||
@ -1708,6 +1718,13 @@ declare module spine {
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
padLeft: string | number;
|
||||
padRight: string | number;
|
||||
padTop: string | number;
|
||||
padBottom: string | number;
|
||||
animations: Map<Viewport>;
|
||||
debugRender: boolean;
|
||||
transitionTime: number;
|
||||
};
|
||||
alpha: boolean;
|
||||
backgroundColor: string;
|
||||
@ -1746,21 +1763,28 @@ declare module spine {
|
||||
private paused;
|
||||
private playTime;
|
||||
private speed;
|
||||
private animationViewports;
|
||||
private currentViewport;
|
||||
private previousViewport;
|
||||
private viewportTransitionStart;
|
||||
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;
|
||||
showSpeedDialog(speedButton: HTMLElement): void;
|
||||
showAnimationsDialog(animationsButton: HTMLElement): void;
|
||||
showSkinsDialog(skinButton: HTMLElement): void;
|
||||
showSettingsDialog(settingsButton: HTMLElement): void;
|
||||
drawFrame(requestNextFrame?: boolean): void;
|
||||
scale(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): Vector2;
|
||||
loadSkeleton(): void;
|
||||
setupInput(): void;
|
||||
private play();
|
||||
private pause();
|
||||
private setAnimation(animation);
|
||||
private percentageToWorldUnit(size, percentageOrAbsolute);
|
||||
private calculateAnimationViewport(animationName);
|
||||
}
|
||||
}
|
||||
declare module spine {
|
||||
|
||||
@ -9402,14 +9402,26 @@ var spine;
|
||||
var spine;
|
||||
(function (spine) {
|
||||
var Popup = (function () {
|
||||
function Popup(parent, htmlContent) {
|
||||
function Popup(player, parent, htmlContent) {
|
||||
this.player = player;
|
||||
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 () {
|
||||
Popup.prototype.show = function (dismissedListener) {
|
||||
var _this = this;
|
||||
if (dismissedListener === void 0) { dismissedListener = function () { }; }
|
||||
this.dom.classList.remove("spine-player-hidden");
|
||||
var dismissed = false;
|
||||
var resize = function () {
|
||||
if (!dismissed)
|
||||
requestAnimationFrame(resize);
|
||||
var bottomOffset = Math.abs(_this.dom.getBoundingClientRect().bottom - _this.player.getBoundingClientRect().bottom);
|
||||
var rightOffset = Math.abs(_this.dom.getBoundingClientRect().right - _this.player.getBoundingClientRect().right);
|
||||
var maxHeight = _this.player.clientHeight - bottomOffset - rightOffset;
|
||||
_this.dom.style.maxHeight = maxHeight + "px";
|
||||
};
|
||||
requestAnimationFrame(resize);
|
||||
var justClicked = true;
|
||||
var windowClickListener = function (event) {
|
||||
if (justClicked) {
|
||||
@ -9419,6 +9431,8 @@ var spine;
|
||||
if (!isContained(_this.dom, event.target)) {
|
||||
_this.dom.parentNode.removeChild(_this.dom);
|
||||
window.removeEventListener("click", windowClickListener);
|
||||
dismissedListener();
|
||||
dismissed = true;
|
||||
}
|
||||
};
|
||||
window.addEventListener("click", windowClickListener);
|
||||
@ -9525,6 +9539,10 @@ var spine;
|
||||
this.paused = true;
|
||||
this.playTime = 0;
|
||||
this.speed = 1;
|
||||
this.animationViewports = {};
|
||||
this.currentViewport = null;
|
||||
this.previousViewport = null;
|
||||
this.viewportTransitionStart = 0;
|
||||
parent.appendChild(this.render());
|
||||
}
|
||||
SpinePlayer.prototype.validateConfig = function (config) {
|
||||
@ -9639,19 +9657,38 @@ var spine;
|
||||
_this.pause();
|
||||
};
|
||||
speedButton.onclick = function () {
|
||||
_this.showSpeedDialog();
|
||||
_this.showSpeedDialog(speedButton);
|
||||
};
|
||||
this.animationButton.onclick = function () {
|
||||
_this.showAnimationsDialog();
|
||||
_this.showAnimationsDialog(_this.animationButton);
|
||||
};
|
||||
this.skinButton.onclick = function () {
|
||||
_this.showSkinsDialog();
|
||||
_this.showSkinsDialog(_this.skinButton);
|
||||
};
|
||||
settingsButton.onclick = function () {
|
||||
_this.showSettingsDialog();
|
||||
_this.showSettingsDialog(settingsButton);
|
||||
};
|
||||
var oldWidth = this.canvas.clientWidth;
|
||||
var oldHeight = this.canvas.clientHeight;
|
||||
var oldStyleWidth = this.canvas.style.width;
|
||||
var oldStyleHeight = this.canvas.style.height;
|
||||
var isFullscreen = false;
|
||||
fullscreenButton.onclick = function () {
|
||||
var fullscreenChanged = function () {
|
||||
isFullscreen = !isFullscreen;
|
||||
if (!isFullscreen) {
|
||||
_this.canvas.style.width = "" + oldWidth + "px";
|
||||
_this.canvas.style.height = "" + oldHeight + "px";
|
||||
_this.drawFrame(false);
|
||||
requestAnimationFrame(function () {
|
||||
_this.canvas.style.width = oldStyleWidth;
|
||||
_this.canvas.style.height = oldStyleHeight;
|
||||
});
|
||||
}
|
||||
};
|
||||
var doc = document;
|
||||
dom.onfullscreenchange = fullscreenChanged;
|
||||
dom.onwebkitfullscreenchange = fullscreenChanged;
|
||||
if (doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement) {
|
||||
if (doc.exitFullscreen)
|
||||
doc.exitFullscreen();
|
||||
@ -9663,6 +9700,10 @@ var spine;
|
||||
doc.msExitFullscreen();
|
||||
}
|
||||
else {
|
||||
oldWidth = _this.canvas.clientWidth;
|
||||
oldHeight = _this.canvas.clientHeight;
|
||||
oldStyleWidth = _this.canvas.style.width;
|
||||
oldStyleHeight = _this.canvas.style.height;
|
||||
var player = dom;
|
||||
if (player.requestFullscreen)
|
||||
player.requestFullscreen();
|
||||
@ -9675,16 +9716,16 @@ var spine;
|
||||
}
|
||||
};
|
||||
logoButton.onclick = function () {
|
||||
window.location = "http://esotericsoftware.com";
|
||||
window.open("http://esotericsoftware.com");
|
||||
};
|
||||
window.onresize = function () {
|
||||
_this.drawFrame(false);
|
||||
};
|
||||
return dom;
|
||||
};
|
||||
SpinePlayer.prototype.showSpeedDialog = function () {
|
||||
SpinePlayer.prototype.showSpeedDialog = function (speedButton) {
|
||||
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 popup = new Popup(this.dom, this.playerControls, "\n\t\t\t\t<div class=\"spine-player-popup-title\">Speed</div>\n\t\t\t\t<hr>\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 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, 0.1, true);
|
||||
sliderParent.appendChild(slider.render());
|
||||
@ -9692,13 +9733,16 @@ var spine;
|
||||
slider.change = function (percentage) {
|
||||
_this.speed = percentage * 2;
|
||||
};
|
||||
popup.show();
|
||||
speedButton.classList.add("spine-player-button-icon-speed-selected");
|
||||
popup.show(function () {
|
||||
speedButton.classList.remove("spine-player-button-icon-speed-selected");
|
||||
});
|
||||
};
|
||||
SpinePlayer.prototype.showAnimationsDialog = function () {
|
||||
SpinePlayer.prototype.showAnimationsDialog = function (animationsButton) {
|
||||
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 popup = new Popup(this.dom, 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) {
|
||||
@ -9714,16 +9758,19 @@ var spine;
|
||||
row.classList.add("selected");
|
||||
_this.config.animation = animation.name;
|
||||
_this.playTime = 0;
|
||||
_this.animationState.setAnimation(0, _this.config.animation, true);
|
||||
_this.setAnimation(animation.name);
|
||||
};
|
||||
});
|
||||
popup.show();
|
||||
animationsButton.classList.add("spine-player-button-icon-animations-selected");
|
||||
popup.show(function () {
|
||||
animationsButton.classList.remove("spine-player-button-icon-animations-selected");
|
||||
});
|
||||
};
|
||||
SpinePlayer.prototype.showSkinsDialog = function () {
|
||||
SpinePlayer.prototype.showSkinsDialog = function (skinButton) {
|
||||
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 popup = new Popup(this.dom, 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) {
|
||||
@ -9742,13 +9789,16 @@ var spine;
|
||||
_this.skeleton.setSlotsToSetupPose();
|
||||
};
|
||||
});
|
||||
popup.show();
|
||||
skinButton.classList.add("spine-player-button-icon-skins-selected");
|
||||
popup.show(function () {
|
||||
skinButton.classList.remove("spine-player-button-icon-skins-selected");
|
||||
});
|
||||
};
|
||||
SpinePlayer.prototype.showSettingsDialog = function () {
|
||||
SpinePlayer.prototype.showSettingsDialog = function (settingsButton) {
|
||||
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 popup = new Popup(this.dom, 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>");
|
||||
@ -9768,7 +9818,10 @@ var spine;
|
||||
makeItem("Clipping", "clipping");
|
||||
makeItem("Points", "points");
|
||||
makeItem("Hulls", "hulls");
|
||||
popup.show();
|
||||
settingsButton.classList.add("spine-player-button-icon-settings-selected");
|
||||
popup.show(function () {
|
||||
settingsButton.classList.remove("spine-player-button-icon-settings-selected");
|
||||
});
|
||||
};
|
||||
SpinePlayer.prototype.drawFrame = function (requestNextFrame) {
|
||||
var _this = this;
|
||||
@ -9802,15 +9855,36 @@ var spine;
|
||||
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;
|
||||
var viewport = {
|
||||
x: this.currentViewport.x - this.currentViewport.padLeft,
|
||||
y: this.currentViewport.y - this.currentViewport.padBottom,
|
||||
width: this.currentViewport.width + this.currentViewport.padLeft + this.currentViewport.padRight,
|
||||
height: this.currentViewport.height + this.currentViewport.padBottom + this.currentViewport.padTop
|
||||
};
|
||||
var transitionAlpha = ((performance.now() - this.viewportTransitionStart) / 1000) / this.config.viewport.transitionTime;
|
||||
if (this.previousViewport && transitionAlpha < 1) {
|
||||
var oldViewport = {
|
||||
x: this.previousViewport.x - this.previousViewport.padLeft,
|
||||
y: this.previousViewport.y - this.previousViewport.padBottom,
|
||||
width: this.previousViewport.width + this.previousViewport.padLeft + this.previousViewport.padRight,
|
||||
height: this.previousViewport.height + this.previousViewport.padBottom + this.previousViewport.padTop
|
||||
};
|
||||
viewport = {
|
||||
x: oldViewport.x + (viewport.x - oldViewport.x) * transitionAlpha,
|
||||
y: oldViewport.y + (viewport.y - oldViewport.y) * transitionAlpha,
|
||||
width: oldViewport.width + (viewport.width - oldViewport.width) * transitionAlpha,
|
||||
height: oldViewport.height + (viewport.height - oldViewport.height) * transitionAlpha
|
||||
};
|
||||
}
|
||||
var viewportSize = this.scale(viewport.width, viewport.height, this.canvas.width, this.canvas.height);
|
||||
this.sceneRenderer.camera.zoom = viewport.width / viewportSize.x;
|
||||
this.sceneRenderer.camera.position.x = viewport.x + viewport.width / 2;
|
||||
this.sceneRenderer.camera.position.y = viewport.y + 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);
|
||||
this.sceneRenderer.drawTexture(bgImage, viewport.x, viewport.y, viewport.width, viewport.height);
|
||||
}
|
||||
else {
|
||||
this.sceneRenderer.drawTexture(bgImage, this.config.backgroundImage.x, this.config.backgroundImage.y, this.config.backgroundImage.width, this.config.backgroundImage.height);
|
||||
@ -9839,6 +9913,10 @@ var spine;
|
||||
this.sceneRenderer.circle(false, skeleton.x + bone.worldX, skeleton.y + bone.worldY, 20, colorOuter);
|
||||
}
|
||||
gl.lineWidth(1);
|
||||
if (this.config.viewport.debugRender) {
|
||||
this.sceneRenderer.rect(false, this.currentViewport.x, this.currentViewport.y, this.currentViewport.width, this.currentViewport.height, spine.Color.GREEN);
|
||||
this.sceneRenderer.rect(false, viewport.x, viewport.y, viewport.width, viewport.height, spine.Color.RED);
|
||||
}
|
||||
this.sceneRenderer.end();
|
||||
this.sceneRenderer.camera.zoom = 0;
|
||||
}
|
||||
@ -9903,21 +9981,27 @@ var spine;
|
||||
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) {
|
||||
if (!this.config.viewport) {
|
||||
this.config.viewport = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0
|
||||
animations: {},
|
||||
debugRender: false,
|
||||
transitionTime: 0.2
|
||||
};
|
||||
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 (typeof this.config.viewport.debugRender === "undefined")
|
||||
this.config.viewport.debugRender = false;
|
||||
if (typeof this.config.viewport.transitionTime === "undefined")
|
||||
this.config.viewport.transitionTime = 0.2;
|
||||
if (!this.config.viewport.animations) {
|
||||
this.config.viewport.animations = {};
|
||||
}
|
||||
else {
|
||||
Object.getOwnPropertyNames(this.config.viewport.animations).forEach(function (animation) {
|
||||
if (!skeletonData.findAnimation(animation)) {
|
||||
_this.showError("Error: animation '" + animation + "' for which a viewport was specified does not exist in skeleton.");
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (this.config.animations && this.config.animations.length > 0) {
|
||||
this.config.animations.forEach(function (animation) {
|
||||
@ -10052,7 +10136,7 @@ var spine;
|
||||
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);
|
||||
this.setAnimation(this.config.animation);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -10061,6 +10145,103 @@ var spine;
|
||||
this.playButton.classList.remove("spine-player-button-icon-pause");
|
||||
this.playButton.classList.add("spine-player-button-icon-play");
|
||||
};
|
||||
SpinePlayer.prototype.setAnimation = function (animation) {
|
||||
this.previousViewport = this.currentViewport;
|
||||
var animViewport = this.calculateAnimationViewport(animation);
|
||||
var viewport = {
|
||||
x: animViewport.x,
|
||||
y: animViewport.y,
|
||||
width: animViewport.width,
|
||||
height: animViewport.height,
|
||||
padLeft: "10%",
|
||||
padRight: "10%",
|
||||
padTop: "10%",
|
||||
padBottom: "10%"
|
||||
};
|
||||
var globalViewport = this.config.viewport;
|
||||
if (typeof globalViewport.x !== "undefined" && typeof globalViewport.y !== "undefined" && typeof globalViewport.width !== "undefined" && typeof globalViewport.height !== "undefined") {
|
||||
viewport.x = globalViewport.x;
|
||||
viewport.y = globalViewport.y;
|
||||
viewport.width = globalViewport.width;
|
||||
viewport.height = globalViewport.height;
|
||||
}
|
||||
if (typeof globalViewport.padLeft !== "undefined")
|
||||
viewport.padLeft = globalViewport.padLeft;
|
||||
if (typeof globalViewport.padRight !== "undefined")
|
||||
viewport.padRight = globalViewport.padRight;
|
||||
if (typeof globalViewport.padTop !== "undefined")
|
||||
viewport.padTop = globalViewport.padTop;
|
||||
if (typeof globalViewport.padBottom !== "undefined")
|
||||
viewport.padBottom = globalViewport.padBottom;
|
||||
var userAnimViewport = this.config.viewport.animations[animation];
|
||||
if (userAnimViewport) {
|
||||
if (typeof userAnimViewport.x !== "undefined" && typeof userAnimViewport.y !== "undefined" && typeof userAnimViewport.width !== "undefined" && typeof userAnimViewport.height !== "undefined") {
|
||||
viewport.x = userAnimViewport.x;
|
||||
viewport.y = userAnimViewport.y;
|
||||
viewport.width = userAnimViewport.width;
|
||||
viewport.height = userAnimViewport.height;
|
||||
}
|
||||
if (typeof userAnimViewport.padLeft !== "undefined")
|
||||
viewport.padLeft = userAnimViewport.padLeft;
|
||||
if (typeof userAnimViewport.padRight !== "undefined")
|
||||
viewport.padRight = userAnimViewport.padRight;
|
||||
if (typeof userAnimViewport.padTop !== "undefined")
|
||||
viewport.padTop = userAnimViewport.padTop;
|
||||
if (typeof userAnimViewport.padBottom !== "undefined")
|
||||
viewport.padBottom = userAnimViewport.padBottom;
|
||||
}
|
||||
viewport.padLeft = this.percentageToWorldUnit(viewport.width, viewport.padLeft);
|
||||
viewport.padRight = this.percentageToWorldUnit(viewport.width, viewport.padRight);
|
||||
viewport.padBottom = this.percentageToWorldUnit(viewport.height, viewport.padBottom);
|
||||
viewport.padTop = this.percentageToWorldUnit(viewport.height, viewport.padTop);
|
||||
this.currentViewport = viewport;
|
||||
this.viewportTransitionStart = performance.now();
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose();
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
};
|
||||
SpinePlayer.prototype.percentageToWorldUnit = function (size, percentageOrAbsolute) {
|
||||
if (typeof percentageOrAbsolute === "string") {
|
||||
return size * parseFloat(percentageOrAbsolute.substr(0, percentageOrAbsolute.length - 1)) / 100;
|
||||
}
|
||||
else {
|
||||
return percentageOrAbsolute;
|
||||
}
|
||||
};
|
||||
SpinePlayer.prototype.calculateAnimationViewport = function (animationName) {
|
||||
var animation = this.skeleton.data.findAnimation(animationName);
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose();
|
||||
this.animationState.setAnimationWith(0, animation, true);
|
||||
var steps = 100;
|
||||
var stepTime = animation.duration > 0 ? animation.duration / steps : 0;
|
||||
var minX = 100000000;
|
||||
var maxX = -100000000;
|
||||
var minY = 100000000;
|
||||
var maxY = -100000000;
|
||||
var offset = new spine.Vector2();
|
||||
var size = new spine.Vector2();
|
||||
for (var i = 0; i < steps; i++) {
|
||||
this.animationState.update(stepTime);
|
||||
this.animationState.apply(this.skeleton);
|
||||
this.skeleton.updateWorldTransform();
|
||||
this.skeleton.getBounds(offset, size);
|
||||
minX = Math.min(offset.x, minX);
|
||||
maxX = Math.max(offset.x + size.x, maxX);
|
||||
minY = Math.min(offset.y, minY);
|
||||
maxY = Math.max(offset.y + size.y, maxY);
|
||||
}
|
||||
offset.x = minX;
|
||||
offset.y = minY;
|
||||
size.x = maxX - minX;
|
||||
size.y = maxY - minY;
|
||||
return {
|
||||
x: offset.x,
|
||||
y: offset.y,
|
||||
width: size.x,
|
||||
height: size.y
|
||||
};
|
||||
};
|
||||
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);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -50,20 +50,20 @@
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 2px;
|
||||
background: rgb(98, 176, 238, 0.6);
|
||||
background: rgba(98, 176, 238, 0.6);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.spine-player-slider:hover .spine-player-slider-value {
|
||||
height: 4px;
|
||||
background: rgb(98, 176, 238, 1);
|
||||
transition: height 0.5s;
|
||||
background: rgba(98, 176, 238, 1);
|
||||
transition: height 0.2s;
|
||||
}
|
||||
|
||||
.spine-player-slider-value.hovering {
|
||||
height: 4px;
|
||||
background: rgb(98, 176, 238, 1);
|
||||
transition: height 0.5s;
|
||||
background: rgba(98, 176, 238, 1);
|
||||
transition: height 0.2s;
|
||||
}
|
||||
|
||||
.spine-player-slider.big {
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
.spine-player-slider.big .spine-player-slider-value {
|
||||
height: 12px;
|
||||
background: rgb(98, 176, 238, 1);
|
||||
background: rgba(98, 176, 238, 1);
|
||||
}
|
||||
|
||||
/** Column and row layout elements **/
|
||||
@ -178,11 +178,12 @@
|
||||
left: 0px;
|
||||
top: -2px;
|
||||
filter: drop-shadow(0 0 1px #333);
|
||||
transition: left 0.2s; /* animates switch changing */
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.spine-player-switch.active .spine-player-switch-knob {
|
||||
background: #fff;
|
||||
left: 18px;
|
||||
transform: translateX(18px);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
/** Popup **/
|
||||
@ -278,6 +279,10 @@
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eplay%3C%2Ftitle%3E%3Cg%20id%3D%22play%22%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2243%2023.3%204%2047%204%201%2043%2023.3%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-play-selected {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eplay%3C%2Ftitle%3E%3Cg%20id%3D%22play%22%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2243%2023.3%204%2047%204%201%2043%2023.3%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-pause {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Epause%3C%2Ftitle%3E%3Cg%20id%3D%22pause%22%3E%3Crect%20class%3D%22cls-1%22%20x%3D%226%22%20y%3D%221%22%20width%3D%2213%22%20height%3D%2246%22%2F%3E%3Crect%20class%3D%22cls-1%22%20x%3D%2228%22%20y%3D%221%22%20width%3D%2213%22%20height%3D%2246%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
@ -286,6 +291,10 @@
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Epause%3C%2Ftitle%3E%3Cg%20id%3D%22pause%22%3E%3Crect%20class%3D%22cls-1%22%20x%3D%226%22%20y%3D%221%22%20width%3D%2213%22%20height%3D%2246%22%2F%3E%3Crect%20class%3D%22cls-1%22%20x%3D%2228%22%20y%3D%221%22%20width%3D%2213%22%20height%3D%2246%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-pause-selected {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Epause%3C%2Ftitle%3E%3Cg%20id%3D%22pause%22%3E%3Crect%20class%3D%22cls-1%22%20x%3D%226%22%20y%3D%221%22%20width%3D%2213%22%20height%3D%2246%22%2F%3E%3Crect%20class%3D%22cls-1%22%20x%3D%2228%22%20y%3D%221%22%20width%3D%2213%22%20height%3D%2246%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-speed {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20id%3D%22playback%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eplayback%3C%2Ftitle%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M48%2C28V20l-4.7-1.18a20.16%2C20.16%2C0%2C0%2C0-2-4.81l2.49-4.15L38.14%2C4.2%2C34%2C6.69a20.16%2C20.16%2C0%2C0%2C0-4.81-2L28%2C0H20L18.82%2C4.7A20.16%2C20.16%2C0%2C0%2C0%2C14%2C6.7L9.86%2C4.2%2C4.2%2C9.86%2C6.69%2C14a20.16%2C20.16%2C0%2C0%2C0-2%2C4.81L0%2C20v8l4.7%2C1.18A20.16%2C20.16%2C0%2C0%2C0%2C6.7%2C34L4.2%2C38.14%2C9.86%2C43.8%2C14%2C41.31a20.16%2C20.16%2C0%2C0%2C0%2C4.81%2C2L20%2C48h8l1.18-4.7a20.16%2C20.16%2C0%2C0%2C0%2C4.81-2l4.15%2C2.49%2C5.66-5.66L41.31%2C34a20.16%2C20.16%2C0%2C0%2C0%2C2-4.81ZM24%2C38A14%2C14%2C0%2C1%2C1%2C38%2C24%2C14%2C14%2C0%2C0%2C1%2C24%2C38Z%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2234%2024%2018%2033%2018%2015%2034%2024%2034%2024%22%2F%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
@ -294,6 +303,10 @@
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20id%3D%22playback%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eplayback%3C%2Ftitle%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M48%2C28V20l-4.7-1.18a20.16%2C20.16%2C0%2C0%2C0-2-4.81l2.49-4.15L38.14%2C4.2%2C34%2C6.69a20.16%2C20.16%2C0%2C0%2C0-4.81-2L28%2C0H20L18.82%2C4.7A20.16%2C20.16%2C0%2C0%2C0%2C14%2C6.7L9.86%2C4.2%2C4.2%2C9.86%2C6.69%2C14a20.16%2C20.16%2C0%2C0%2C0-2%2C4.81L0%2C20v8l4.7%2C1.18A20.16%2C20.16%2C0%2C0%2C0%2C6.7%2C34L4.2%2C38.14%2C9.86%2C43.8%2C14%2C41.31a20.16%2C20.16%2C0%2C0%2C0%2C4.81%2C2L20%2C48h8l1.18-4.7a20.16%2C20.16%2C0%2C0%2C0%2C4.81-2l4.15%2C2.49%2C5.66-5.66L41.31%2C34a20.16%2C20.16%2C0%2C0%2C0%2C2-4.81ZM24%2C38A14%2C14%2C0%2C1%2C1%2C38%2C24%2C14%2C14%2C0%2C0%2C1%2C24%2C38Z%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2234%2024%2018%2033%2018%2015%2034%2024%2034%2024%22%2F%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-speed-selected {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20id%3D%22playback%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eplayback%3C%2Ftitle%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M48%2C28V20l-4.7-1.18a20.16%2C20.16%2C0%2C0%2C0-2-4.81l2.49-4.15L38.14%2C4.2%2C34%2C6.69a20.16%2C20.16%2C0%2C0%2C0-4.81-2L28%2C0H20L18.82%2C4.7A20.16%2C20.16%2C0%2C0%2C0%2C14%2C6.7L9.86%2C4.2%2C4.2%2C9.86%2C6.69%2C14a20.16%2C20.16%2C0%2C0%2C0-2%2C4.81L0%2C20v8l4.7%2C1.18A20.16%2C20.16%2C0%2C0%2C0%2C6.7%2C34L4.2%2C38.14%2C9.86%2C43.8%2C14%2C41.31a20.16%2C20.16%2C0%2C0%2C0%2C4.81%2C2L20%2C48h8l1.18-4.7a20.16%2C20.16%2C0%2C0%2C0%2C4.81-2l4.15%2C2.49%2C5.66-5.66L41.31%2C34a20.16%2C20.16%2C0%2C0%2C0%2C2-4.81ZM24%2C38A14%2C14%2C0%2C1%2C1%2C38%2C24%2C14%2C14%2C0%2C0%2C1%2C24%2C38Z%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2234%2024%2018%2033%2018%2015%2034%2024%2034%2024%22%2F%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-animations {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eanimations%3C%2Ftitle%3E%3Cg%20id%3D%22animations%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M12%2C45V43.22a6.39%2C6.39%2C0%2C0%2C0%2C.63-.81%2C27.83%2C27.83%2C0%2C0%2C1%2C3.79-4.16c.93-.84%2C2.06-1.88%2C2.86-2.71a13.83%2C13.83%2C0%2C0%2C0%2C1.53-1.9l3.9-5.24c1-1.17.95-1.1%2C2.11%2C0l3%2C2.24a4%2C4%2C0%2C0%2C0-2.29%2C2.38c-1.37%2C3-2.39%2C4-2.68%2C4.22l-.23.18c-.54.39-1.81%2C1-1.7%2C1.54l.8%2C1.49a4.5%2C4.5%2C0%2C0%2C1%2C.39%2C1l.57%2C2.15a.69.69%2C0%2C0%2C0%2C.58.48c.47.08%2C1%2C.5%2C1.33.53%2C1.29.1%2C1.79%2C0%2C1.42-.54L26.7%2C42.72a.86.86%2C0%2C0%2C1-.2-.24%2C3.64%2C3.64%2C0%2C0%2C1-.42-2.2A5.39%2C5.39%2C0%2C0%2C1%2C26.61%2C39c1.84-2%2C6.74-6.36%2C6.74-6.36%2C1.71-1.81%2C1.4-2.52.81-3.84a27.38%2C27.38%2C0%2C0%2C0-2-3c-.41-.61-2.08-2.38-2.85-3.28-.43-.5.38-2.08.87-2.82.18-.12-.41.05%2C1.72.07a23.32%2C23.32%2C0%2C0%2C0%2C3.56-.19l1.63.61c.28%2C0%2C1.18-.09%2C1.31-.35l.12-.78c.18-.39.31-1.56-.05-1.75l-.6-.52a2.28%2C2.28%2C0%2C0%2C0-1.61.07l-.2.44c-.14.15-.52.37-.71.29l-2.24%2C0c-.5.12-1.18-.42-1.81-.73L32.05%2C15a8%2C8%2C0%2C0%2C0%2C.8-3.92%2C1.22%2C1.22%2C0%2C0%2C0-.28-.82%2C7.87%2C7.87%2C0%2C0%2C0-1.15-1.06l.11-.73c-.12-.49%2C1-.82%2C1.52-.82l.76-.33c.32%2C0%2C.68-.89.78-1.21L34.94%2C4a11.26%2C11.26%2C0%2C0%2C0%2C0-1.61C34.57.08%2C30.06-1.42%2C28.78%2C2c-.14.38-.62.77.34%2C3.21a1.55%2C1.55%2C0%2C0%2C1-.3%2C1.2L28.4%2C7a4%2C4%2C0%2C0%2C1-1.19.49c-.79%2C0-1.59-.75-4%2C.54C21%2C9.16%2C18.59%2C13%2C17.7%2C14.22a3.21%2C3.21%2C0%2C0%2C0-.61%2C1.58c-.05%2C1.16.7%2C3.74.87%2C5.75.13%2C1.53.21%2C2.52.72%2C3.06%2C1.07%2C1.14%2C2.1-.18%2C2.61-1a2.74%2C2.74%2C0%2C0%2C0-.14-1.86l-.74-.1c-.15-.15-.4-.42-.39-.64-.05-3.48-.22-3.14-.18-5.39%2C1.74-1.46%2C2.4-2.45%2C2.3-2-.2%2C1.15.28%2C2.83.09%2C4.35a6.46%2C6.46%2C0%2C0%2C1-.7%2C2.58s-2.11%2C4.22-2.14%2C4.27l-1.26%2C5.6-.7%2C1.44s-.71.54-1.59%2C1.21a9.67%2C9.67%2C0%2C0%2C0-2.27%2C3.18%2C20.16%2C20.16%2C0%2C0%2C1-1.42%2C2.83l-.87%2C1.31a1.72%2C1.72%2C0%2C0%2C1-.6.61l-1.83%2C1.1a1.39%2C1.39%2C0%2C0%2C0-.16.93l.68%2C1.71a4.07%2C4.07%2C0%2C0%2C1%2C.27%2C1.07l.17%2C1.56a.75.75%2C0%2C0%2C0%2C.71.59%2C18.13%2C18.13%2C0%2C0%2C0%2C3.26-.5c.27-.09-.29-.78-.53-1s-.45-.36-.45-.36A12.78%2C12.78%2C0%2C0%2C1%2C12%2C45Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
|
||||
}
|
||||
@ -302,6 +315,10 @@
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eanimations%3C%2Ftitle%3E%3Cg%20id%3D%22animations%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M12%2C45V43.22a6.39%2C6.39%2C0%2C0%2C0%2C.63-.81%2C27.83%2C27.83%2C0%2C0%2C1%2C3.79-4.16c.93-.84%2C2.06-1.88%2C2.86-2.71a13.83%2C13.83%2C0%2C0%2C0%2C1.53-1.9l3.9-5.24c1-1.17.95-1.1%2C2.11%2C0l3%2C2.24a4%2C4%2C0%2C0%2C0-2.29%2C2.38c-1.37%2C3-2.39%2C4-2.68%2C4.22l-.23.18c-.54.39-1.81%2C1-1.7%2C1.54l.8%2C1.49a4.5%2C4.5%2C0%2C0%2C1%2C.39%2C1l.57%2C2.15a.69.69%2C0%2C0%2C0%2C.58.48c.47.08%2C1%2C.5%2C1.33.53%2C1.29.1%2C1.79%2C0%2C1.42-.54L26.7%2C42.72a.86.86%2C0%2C0%2C1-.2-.24%2C3.64%2C3.64%2C0%2C0%2C1-.42-2.2A5.39%2C5.39%2C0%2C0%2C1%2C26.61%2C39c1.84-2%2C6.74-6.36%2C6.74-6.36%2C1.71-1.81%2C1.4-2.52.81-3.84a27.38%2C27.38%2C0%2C0%2C0-2-3c-.41-.61-2.08-2.38-2.85-3.28-.43-.5.38-2.08.87-2.82.18-.12-.41.05%2C1.72.07a23.32%2C23.32%2C0%2C0%2C0%2C3.56-.19l1.63.61c.28%2C0%2C1.18-.09%2C1.31-.35l.12-.78c.18-.39.31-1.56-.05-1.75l-.6-.52a2.28%2C2.28%2C0%2C0%2C0-1.61.07l-.2.44c-.14.15-.52.37-.71.29l-2.24%2C0c-.5.12-1.18-.42-1.81-.73L32.05%2C15a8%2C8%2C0%2C0%2C0%2C.8-3.92%2C1.22%2C1.22%2C0%2C0%2C0-.28-.82%2C7.87%2C7.87%2C0%2C0%2C0-1.15-1.06l.11-.73c-.12-.49%2C1-.82%2C1.52-.82l.76-.33c.32%2C0%2C.68-.89.78-1.21L34.94%2C4a11.26%2C11.26%2C0%2C0%2C0%2C0-1.61C34.57.08%2C30.06-1.42%2C28.78%2C2c-.14.38-.62.77.34%2C3.21a1.55%2C1.55%2C0%2C0%2C1-.3%2C1.2L28.4%2C7a4%2C4%2C0%2C0%2C1-1.19.49c-.79%2C0-1.59-.75-4%2C.54C21%2C9.16%2C18.59%2C13%2C17.7%2C14.22a3.21%2C3.21%2C0%2C0%2C0-.61%2C1.58c-.05%2C1.16.7%2C3.74.87%2C5.75.13%2C1.53.21%2C2.52.72%2C3.06%2C1.07%2C1.14%2C2.1-.18%2C2.61-1a2.74%2C2.74%2C0%2C0%2C0-.14-1.86l-.74-.1c-.15-.15-.4-.42-.39-.64-.05-3.48-.22-3.14-.18-5.39%2C1.74-1.46%2C2.4-2.45%2C2.3-2-.2%2C1.15.28%2C2.83.09%2C4.35a6.46%2C6.46%2C0%2C0%2C1-.7%2C2.58s-2.11%2C4.22-2.14%2C4.27l-1.26%2C5.6-.7%2C1.44s-.71.54-1.59%2C1.21a9.67%2C9.67%2C0%2C0%2C0-2.27%2C3.18%2C20.16%2C20.16%2C0%2C0%2C1-1.42%2C2.83l-.87%2C1.31a1.72%2C1.72%2C0%2C0%2C1-.6.61l-1.83%2C1.1a1.39%2C1.39%2C0%2C0%2C0-.16.93l.68%2C1.71a4.07%2C4.07%2C0%2C0%2C1%2C.27%2C1.07l.17%2C1.56a.75.75%2C0%2C0%2C0%2C.71.59%2C18.13%2C18.13%2C0%2C0%2C0%2C3.26-.5c.27-.09-.29-.78-.53-1s-.45-.36-.45-.36A12.78%2C12.78%2C0%2C0%2C1%2C12%2C45Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
|
||||
}
|
||||
|
||||
.spine-player-button-icon-animations-selected {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eanimations%3C%2Ftitle%3E%3Cg%20id%3D%22animations%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M12%2C45V43.22a6.39%2C6.39%2C0%2C0%2C0%2C.63-.81%2C27.83%2C27.83%2C0%2C0%2C1%2C3.79-4.16c.93-.84%2C2.06-1.88%2C2.86-2.71a13.83%2C13.83%2C0%2C0%2C0%2C1.53-1.9l3.9-5.24c1-1.17.95-1.1%2C2.11%2C0l3%2C2.24a4%2C4%2C0%2C0%2C0-2.29%2C2.38c-1.37%2C3-2.39%2C4-2.68%2C4.22l-.23.18c-.54.39-1.81%2C1-1.7%2C1.54l.8%2C1.49a4.5%2C4.5%2C0%2C0%2C1%2C.39%2C1l.57%2C2.15a.69.69%2C0%2C0%2C0%2C.58.48c.47.08%2C1%2C.5%2C1.33.53%2C1.29.1%2C1.79%2C0%2C1.42-.54L26.7%2C42.72a.86.86%2C0%2C0%2C1-.2-.24%2C3.64%2C3.64%2C0%2C0%2C1-.42-2.2A5.39%2C5.39%2C0%2C0%2C1%2C26.61%2C39c1.84-2%2C6.74-6.36%2C6.74-6.36%2C1.71-1.81%2C1.4-2.52.81-3.84a27.38%2C27.38%2C0%2C0%2C0-2-3c-.41-.61-2.08-2.38-2.85-3.28-.43-.5.38-2.08.87-2.82.18-.12-.41.05%2C1.72.07a23.32%2C23.32%2C0%2C0%2C0%2C3.56-.19l1.63.61c.28%2C0%2C1.18-.09%2C1.31-.35l.12-.78c.18-.39.31-1.56-.05-1.75l-.6-.52a2.28%2C2.28%2C0%2C0%2C0-1.61.07l-.2.44c-.14.15-.52.37-.71.29l-2.24%2C0c-.5.12-1.18-.42-1.81-.73L32.05%2C15a8%2C8%2C0%2C0%2C0%2C.8-3.92%2C1.22%2C1.22%2C0%2C0%2C0-.28-.82%2C7.87%2C7.87%2C0%2C0%2C0-1.15-1.06l.11-.73c-.12-.49%2C1-.82%2C1.52-.82l.76-.33c.32%2C0%2C.68-.89.78-1.21L34.94%2C4a11.26%2C11.26%2C0%2C0%2C0%2C0-1.61C34.57.08%2C30.06-1.42%2C28.78%2C2c-.14.38-.62.77.34%2C3.21a1.55%2C1.55%2C0%2C0%2C1-.3%2C1.2L28.4%2C7a4%2C4%2C0%2C0%2C1-1.19.49c-.79%2C0-1.59-.75-4%2C.54C21%2C9.16%2C18.59%2C13%2C17.7%2C14.22a3.21%2C3.21%2C0%2C0%2C0-.61%2C1.58c-.05%2C1.16.7%2C3.74.87%2C5.75.13%2C1.53.21%2C2.52.72%2C3.06%2C1.07%2C1.14%2C2.1-.18%2C2.61-1a2.74%2C2.74%2C0%2C0%2C0-.14-1.86l-.74-.1c-.15-.15-.4-.42-.39-.64-.05-3.48-.22-3.14-.18-5.39%2C1.74-1.46%2C2.4-2.45%2C2.3-2-.2%2C1.15.28%2C2.83.09%2C4.35a6.46%2C6.46%2C0%2C0%2C1-.7%2C2.58s-2.11%2C4.22-2.14%2C4.27l-1.26%2C5.6-.7%2C1.44s-.71.54-1.59%2C1.21a9.67%2C9.67%2C0%2C0%2C0-2.27%2C3.18%2C20.16%2C20.16%2C0%2C0%2C1-1.42%2C2.83l-.87%2C1.31a1.72%2C1.72%2C0%2C0%2C1-.6.61l-1.83%2C1.1a1.39%2C1.39%2C0%2C0%2C0-.16.93l.68%2C1.71a4.07%2C4.07%2C0%2C0%2C1%2C.27%2C1.07l.17%2C1.56a.75.75%2C0%2C0%2C0%2C.71.59%2C18.13%2C18.13%2C0%2C0%2C0%2C3.26-.5c.27-.09-.29-.78-.53-1s-.45-.36-.45-.36A12.78%2C12.78%2C0%2C0%2C1%2C12%2C45Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
|
||||
}
|
||||
|
||||
.spine-player-button-icon-skins {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eskins%3C%2Ftitle%3E%3Cg%20id%3D%22skins%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M36%2C12.54l-6.92%2C1-.79%2C1.2c-1%2C.25-2-.62-3-.55V12.33a1.35%2C1.35%2C0%2C0%2C1%2C.55-1.07c3-2.24%2C3.28-3.75%2C3.28-5.34A5.06%2C5.06%2C0%2C0%2C0%2C24%2C.76c-2.54%2C0-4.38.71-5.49%2C2.13a5.74%2C5.74%2C0%2C0%2C0-.9%2C4.57l2.48-.61a3.17%2C3.17%2C0%2C0%2C1%2C.45-2.4c.6-.75%2C1.75-1.13%2C3.42-1.13%2C2.56%2C0%2C2.56%2C1.24%2C2.56%2C2.56%2C0%2C.92%2C0%2C1.65-2.26%2C3.34a3.92%2C3.92%2C0%2C0%2C0-1.58%2C3.12v1.86c-1-.07-2%2C.8-3%2C.55l-.79-1.2-6.92-1c-2.25%2C0-4.35%2C2.09-5.64%2C3.93L1%2C24c3.83%2C5.11%2C10.22%2C5.11%2C10.22%2C5.11V41.93c0%2C2.34%2C2.68%2C3.88%2C5.59%2C4.86a22.59%2C22.59%2C0%2C0%2C0%2C14.37%2C0c2.91-1%2C5.59-2.52%2C5.59-4.86V29.15S43.17%2C29.15%2C47%2C24l-5.33-7.57C40.38%2C14.63%2C38.27%2C12.54%2C36%2C12.54ZM23.32%2C20.09%2C21%2C17l1.8-.6a3.79%2C3.79%2C0%2C0%2C1%2C2.4%2C0L27%2C17l-2.32%2C3.09A.85.85%2C0%2C0%2C1%2C23.32%2C20.09Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
width: 31px;
|
||||
@ -312,6 +329,10 @@
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eskins%3C%2Ftitle%3E%3Cg%20id%3D%22skins%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M36%2C12.54l-6.92%2C1-.79%2C1.2c-1%2C.25-2-.62-3-.55V12.33a1.35%2C1.35%2C0%2C0%2C1%2C.55-1.07c3-2.24%2C3.28-3.75%2C3.28-5.34A5.06%2C5.06%2C0%2C0%2C0%2C24%2C.76c-2.54%2C0-4.38.71-5.49%2C2.13a5.74%2C5.74%2C0%2C0%2C0-.9%2C4.57l2.48-.61a3.17%2C3.17%2C0%2C0%2C1%2C.45-2.4c.6-.75%2C1.75-1.13%2C3.42-1.13%2C2.56%2C0%2C2.56%2C1.24%2C2.56%2C2.56%2C0%2C.92%2C0%2C1.65-2.26%2C3.34a3.92%2C3.92%2C0%2C0%2C0-1.58%2C3.12v1.86c-1-.07-2%2C.8-3%2C.55l-.79-1.2-6.92-1c-2.25%2C0-4.35%2C2.09-5.64%2C3.93L1%2C24c3.83%2C5.11%2C10.22%2C5.11%2C10.22%2C5.11V41.93c0%2C2.34%2C2.68%2C3.88%2C5.59%2C4.86a22.59%2C22.59%2C0%2C0%2C0%2C14.37%2C0c2.91-1%2C5.59-2.52%2C5.59-4.86V29.15S43.17%2C29.15%2C47%2C24l-5.33-7.57C40.38%2C14.63%2C38.27%2C12.54%2C36%2C12.54ZM23.32%2C20.09%2C21%2C17l1.8-.6a3.79%2C3.79%2C0%2C0%2C1%2C2.4%2C0L27%2C17l-2.32%2C3.09A.85.85%2C0%2C0%2C1%2C23.32%2C20.09Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-skins-selected {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eskins%3C%2Ftitle%3E%3Cg%20id%3D%22skins%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M36%2C12.54l-6.92%2C1-.79%2C1.2c-1%2C.25-2-.62-3-.55V12.33a1.35%2C1.35%2C0%2C0%2C1%2C.55-1.07c3-2.24%2C3.28-3.75%2C3.28-5.34A5.06%2C5.06%2C0%2C0%2C0%2C24%2C.76c-2.54%2C0-4.38.71-5.49%2C2.13a5.74%2C5.74%2C0%2C0%2C0-.9%2C4.57l2.48-.61a3.17%2C3.17%2C0%2C0%2C1%2C.45-2.4c.6-.75%2C1.75-1.13%2C3.42-1.13%2C2.56%2C0%2C2.56%2C1.24%2C2.56%2C2.56%2C0%2C.92%2C0%2C1.65-2.26%2C3.34a3.92%2C3.92%2C0%2C0%2C0-1.58%2C3.12v1.86c-1-.07-2%2C.8-3%2C.55l-.79-1.2-6.92-1c-2.25%2C0-4.35%2C2.09-5.64%2C3.93L1%2C24c3.83%2C5.11%2C10.22%2C5.11%2C10.22%2C5.11V41.93c0%2C2.34%2C2.68%2C3.88%2C5.59%2C4.86a22.59%2C22.59%2C0%2C0%2C0%2C14.37%2C0c2.91-1%2C5.59-2.52%2C5.59-4.86V29.15S43.17%2C29.15%2C47%2C24l-5.33-7.57C40.38%2C14.63%2C38.27%2C12.54%2C36%2C12.54ZM23.32%2C20.09%2C21%2C17l1.8-.6a3.79%2C3.79%2C0%2C0%2C1%2C2.4%2C0L27%2C17l-2.32%2C3.09A.85.85%2C0%2C0%2C1%2C23.32%2C20.09Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-settings {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Esettings%3C%2Ftitle%3E%3Cg%20id%3D%22settings%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M40%2C3H8A5%2C5%2C0%2C0%2C0%2C3%2C8V40a5%2C5%2C0%2C0%2C0%2C5%2C5H40a5%2C5%2C0%2C0%2C0%2C5-5V8A5%2C5%2C0%2C0%2C0%2C40%2C3ZM16%2C40H9V33h7Zm0-12H9V21h7Zm0-12H9V9h7ZM39%2C38H20V35H39Zm0-12H20V23H39Zm0-12H20V11H39Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
margin-top: 1px;
|
||||
@ -321,6 +342,10 @@
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Esettings%3C%2Ftitle%3E%3Cg%20id%3D%22settings%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M40%2C3H8A5%2C5%2C0%2C0%2C0%2C3%2C8V40a5%2C5%2C0%2C0%2C0%2C5%2C5H40a5%2C5%2C0%2C0%2C0%2C5-5V8A5%2C5%2C0%2C0%2C0%2C40%2C3ZM16%2C40H9V33h7Zm0-12H9V21h7Zm0-12H9V9h7ZM39%2C38H20V35H39Zm0-12H20V23H39Zm0-12H20V11H39Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-settings-selected {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Esettings%3C%2Ftitle%3E%3Cg%20id%3D%22settings%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M40%2C3H8A5%2C5%2C0%2C0%2C0%2C3%2C8V40a5%2C5%2C0%2C0%2C0%2C5%2C5H40a5%2C5%2C0%2C0%2C0%2C5-5V8A5%2C5%2C0%2C0%2C0%2C40%2C3ZM16%2C40H9V33h7Zm0-12H9V21h7Zm0-12H9V9h7ZM39%2C38H20V35H39Zm0-12H20V23H39Zm0-12H20V11H39Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-fullscreen {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eexpand%3C%2Ftitle%3E%3Cg%20id%3D%22settings%22%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2230.14%208%2040%208%2040%2017.86%2044.5%2017.86%2044.5%203.5%2030.14%203.5%2030.14%208%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%228%2017.86%208%208%2017.86%208%2017.86%203.5%203.5%203.5%203.5%2017.86%208%2017.86%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2240%2030.14%2040%2040%2030.14%2040%2030.14%2044.5%2044.5%2044.5%2044.5%2030.14%2040%2030.14%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2217.86%2040%208%2040%208%2030.14%203.5%2030.14%203.5%2044.5%2017.86%2044.5%2017.86%2040%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
margin-top: 1px;
|
||||
@ -330,6 +355,10 @@
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eexpand%3C%2Ftitle%3E%3Cg%20id%3D%22settings%22%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2230.14%208%2040%208%2040%2017.86%2044.5%2017.86%2044.5%203.5%2030.14%203.5%2030.14%208%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%228%2017.86%208%208%2017.86%208%2017.86%203.5%203.5%203.5%203.5%2017.86%208%2017.86%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2240%2030.14%2040%2040%2030.14%2040%2030.14%2044.5%2044.5%2044.5%2044.5%2030.14%2040%2030.14%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2217.86%2040%208%2040%208%2030.14%203.5%2030.14%203.5%2044.5%2017.86%2044.5%2017.86%2040%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-fullscreen-selected {
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%2362B0EE%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eexpand%3C%2Ftitle%3E%3Cg%20id%3D%22settings%22%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2230.14%208%2040%208%2040%2017.86%2044.5%2017.86%2044.5%203.5%2030.14%203.5%2030.14%208%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%228%2017.86%208%208%2017.86%208%2017.86%203.5%203.5%203.5%203.5%2017.86%208%2017.86%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2240%2030.14%2040%2040%2030.14%2040%2030.14%2044.5%2044.5%2044.5%2044.5%2030.14%2040%2030.14%22%2F%3E%3Cpolygon%20class%3D%22cls-1%22%20points%3D%2217.86%2040%208%2040%208%2030.14%203.5%2030.14%203.5%2044.5%2017.86%2044.5%2017.86%2040%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
||||
}
|
||||
|
||||
.spine-player-button-icon-spine-logo {
|
||||
height: 20px;
|
||||
position: relative;
|
||||
@ -340,6 +369,8 @@
|
||||
width: auto !important;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
box-shadow: none !important;
|
||||
filter: drop-shadow(0 0 1px #333);
|
||||
}
|
||||
|
||||
.spine-player-button-icon-spine-logo:hover {
|
||||
|
||||
@ -15,17 +15,17 @@ body {
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div id="container" style="width: 480px; height: 320px;"></div>
|
||||
<div id="container" style="width: 100%; height: 90vh;"></div>
|
||||
</body>
|
||||
<script>
|
||||
new spine.SpinePlayer(document.getElementById("container"), {
|
||||
jsonUrl: "assets/spineboy-pro.json",
|
||||
atlasUrl: "assets/spineboy-pma.atlas",
|
||||
premultipliedAlpha: true,
|
||||
animations: ["walk", "jump"],
|
||||
controlBones: ["root"],
|
||||
backgroundColor: "#cccccc",
|
||||
fullScreenBackgroundColor: "#cc0000",
|
||||
viewport: {
|
||||
debugRender: true,
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@ -29,6 +29,17 @@
|
||||
*****************************************************************************/
|
||||
|
||||
module spine {
|
||||
export interface Viewport {
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
padLeft: string | number
|
||||
padRight: string | number
|
||||
padTop: string | number
|
||||
padBottom: string | number
|
||||
}
|
||||
|
||||
export interface SpinePlayerConfig {
|
||||
/* the URL of the skeleton .json file */
|
||||
jsonUrl: string
|
||||
@ -75,6 +86,13 @@
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
padLeft: string | number
|
||||
padRight: string | number
|
||||
padTop: string | number
|
||||
padBottom: string | number
|
||||
animations: Map<Viewport>
|
||||
debugRender: boolean,
|
||||
transitionTime: number
|
||||
}
|
||||
|
||||
/* Optional: whether the canvas should be transparent. Default: false. */
|
||||
@ -108,7 +126,7 @@
|
||||
class Popup {
|
||||
public dom: HTMLElement;
|
||||
|
||||
constructor(parent: HTMLElement, htmlContent: string) {
|
||||
constructor(private player: HTMLElement, parent: HTMLElement, htmlContent: string) {
|
||||
this.dom = createElement(/*html*/`
|
||||
<div class="spine-player-popup spine-player-hidden">
|
||||
</div>
|
||||
@ -117,8 +135,22 @@
|
||||
parent.appendChild(this.dom);
|
||||
}
|
||||
|
||||
show () {
|
||||
show (dismissedListener = () => {}) {
|
||||
this.dom.classList.remove("spine-player-hidden");
|
||||
|
||||
// Make sure the popup isn't bigger than the player.
|
||||
var dismissed = false;
|
||||
let resize = () => {
|
||||
if (!dismissed) requestAnimationFrame(resize);
|
||||
let bottomOffset = Math.abs(this.dom.getBoundingClientRect().bottom - this.player.getBoundingClientRect().bottom);
|
||||
let rightOffset = Math.abs(this.dom.getBoundingClientRect().right - this.player.getBoundingClientRect().right);
|
||||
let maxHeight = this.player.clientHeight - bottomOffset - rightOffset;
|
||||
this.dom.style.maxHeight = maxHeight + "px";
|
||||
}
|
||||
requestAnimationFrame(resize);
|
||||
|
||||
// Dismiss when clicking somewhere else outside
|
||||
// the popup
|
||||
var justClicked = true;
|
||||
let windowClickListener = (event: any) => {
|
||||
if (justClicked) {
|
||||
@ -128,6 +160,8 @@
|
||||
if (!isContained(this.dom, event.target)) {
|
||||
this.dom.parentNode.removeChild(this.dom);
|
||||
window.removeEventListener("click", windowClickListener);
|
||||
dismissedListener();
|
||||
dismissed = true;
|
||||
}
|
||||
}
|
||||
window.addEventListener("click", windowClickListener);
|
||||
@ -217,6 +251,8 @@
|
||||
if (this.change) this.change(percentage);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return this.slider;
|
||||
}
|
||||
|
||||
@ -265,6 +301,11 @@
|
||||
private playTime = 0;
|
||||
private speed = 1;
|
||||
|
||||
private animationViewports: Map<Viewport> = {}
|
||||
private currentViewport: Viewport = null;
|
||||
private previousViewport: Viewport = null;
|
||||
private viewportTransitionStart = 0;
|
||||
|
||||
private selectedBones: Bone[];
|
||||
|
||||
constructor(parent: HTMLElement, private config: SpinePlayerConfig) {
|
||||
@ -396,29 +437,56 @@
|
||||
}
|
||||
|
||||
speedButton.onclick = () => {
|
||||
this.showSpeedDialog();
|
||||
this.showSpeedDialog(speedButton);
|
||||
}
|
||||
|
||||
this.animationButton.onclick = () => {
|
||||
this.showAnimationsDialog();
|
||||
this.showAnimationsDialog(this.animationButton);
|
||||
}
|
||||
|
||||
this.skinButton.onclick = () => {
|
||||
this.showSkinsDialog();
|
||||
this.showSkinsDialog(this.skinButton);
|
||||
}
|
||||
|
||||
settingsButton.onclick = () => {
|
||||
this.showSettingsDialog();
|
||||
this.showSettingsDialog(settingsButton);
|
||||
}
|
||||
|
||||
let oldWidth = this.canvas.clientWidth;
|
||||
let oldHeight = this.canvas.clientHeight;
|
||||
let oldStyleWidth = this.canvas.style.width;
|
||||
let oldStyleHeight = this.canvas.style.height;
|
||||
var isFullscreen = false;
|
||||
fullscreenButton.onclick = () => {
|
||||
let fullscreenChanged = () => {
|
||||
isFullscreen = !isFullscreen;
|
||||
if (!isFullscreen) {
|
||||
this.canvas.style.width = "" + oldWidth + "px";
|
||||
this.canvas.style.height = "" + oldHeight + "px";
|
||||
this.drawFrame(false);
|
||||
// Got to reset the style to whatever the user set
|
||||
// after the next layouting.
|
||||
requestAnimationFrame(() => {
|
||||
this.canvas.style.width = oldStyleWidth;
|
||||
this.canvas.style.height = oldStyleHeight;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let doc = document as any;
|
||||
(dom as any).onfullscreenchange = fullscreenChanged;
|
||||
dom.onwebkitfullscreenchange = fullscreenChanged;
|
||||
|
||||
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 {
|
||||
oldWidth = this.canvas.clientWidth;
|
||||
oldHeight = this.canvas.clientHeight;
|
||||
oldStyleWidth = this.canvas.style.width;
|
||||
oldStyleHeight = this.canvas.style.height;
|
||||
let player = dom as any;
|
||||
if (player.requestFullscreen) player.requestFullscreen();
|
||||
else if (player.webkitRequestFullScreen) player.webkitRequestFullScreen();
|
||||
@ -428,7 +496,7 @@
|
||||
};
|
||||
|
||||
logoButton.onclick = () => {
|
||||
(window.location as any)= "http://esotericsoftware.com";
|
||||
window.open("http://esotericsoftware.com");
|
||||
};
|
||||
|
||||
// Register a global resize handler to redraw and avoid flicker
|
||||
@ -439,10 +507,11 @@
|
||||
return dom;
|
||||
}
|
||||
|
||||
showSpeedDialog () {
|
||||
let popup = new Popup(this.playerControls, /*html*/`
|
||||
showSpeedDialog (speedButton: HTMLElement) {
|
||||
let popup = new Popup(this.dom, this.playerControls, /*html*/`
|
||||
<div class="spine-player-popup-title">Speed</div>
|
||||
<hr>
|
||||
<div class="spine-player-row" style="user-select: none; align-items: center; padding: 8px;">
|
||||
<div style="margin-right: 16px;">Speed</div>
|
||||
<div class="spine-player-column">
|
||||
<div class="spine-player-speed-slider" style="margin-bottom: 4px;"></div>
|
||||
<div class="spine-player-row" style="justify-content: space-between;">
|
||||
@ -460,13 +529,16 @@
|
||||
slider.change = (percentage) => {
|
||||
this.speed = percentage * 2;
|
||||
}
|
||||
popup.show();
|
||||
speedButton.classList.add("spine-player-button-icon-speed-selected")
|
||||
popup.show(() => {
|
||||
speedButton.classList.remove("spine-player-button-icon-speed-selected")
|
||||
});
|
||||
}
|
||||
|
||||
showAnimationsDialog () {
|
||||
showAnimationsDialog (animationsButton: HTMLElement) {
|
||||
if (!this.skeleton || this.skeleton.data.animations.length == 0) return;
|
||||
|
||||
let popup = new Popup(this.playerControls, /*html*/`
|
||||
let popup = new Popup(this.dom, this.playerControls, /*html*/`
|
||||
<div class="spine-player-popup-title">Animations</div>
|
||||
<hr>
|
||||
<ul class="spine-player-list"></ul>
|
||||
@ -495,16 +567,19 @@
|
||||
row.classList.add("selected");
|
||||
this.config.animation = animation.name;
|
||||
this.playTime = 0;
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
this.setAnimation(animation.name);
|
||||
}
|
||||
});
|
||||
popup.show();
|
||||
animationsButton.classList.add("spine-player-button-icon-animations-selected")
|
||||
popup.show(() => {
|
||||
animationsButton.classList.remove("spine-player-button-icon-animations-selected")
|
||||
});
|
||||
}
|
||||
|
||||
showSkinsDialog () {
|
||||
showSkinsDialog (skinButton: HTMLElement) {
|
||||
if (!this.skeleton || this.skeleton.data.animations.length == 0) return;
|
||||
|
||||
let popup = new Popup(this.playerControls, /*html*/`
|
||||
let popup = new Popup(this.dom, this.playerControls, /*html*/`
|
||||
<div class="spine-player-popup-title">Skins</div>
|
||||
<hr>
|
||||
<ul class="spine-player-list"></ul>
|
||||
@ -537,13 +612,16 @@
|
||||
}
|
||||
});
|
||||
|
||||
popup.show();
|
||||
skinButton.classList.add("spine-player-button-icon-skins-selected")
|
||||
popup.show(() => {
|
||||
skinButton.classList.remove("spine-player-button-icon-skins-selected")
|
||||
});
|
||||
}
|
||||
|
||||
showSettingsDialog () {
|
||||
showSettingsDialog (settingsButton: HTMLElement) {
|
||||
if (!this.skeleton || this.skeleton.data.animations.length == 0) return;
|
||||
|
||||
let popup = new Popup(this.playerControls, /*html*/`
|
||||
let popup = new Popup(this.dom, this.playerControls, /*html*/`
|
||||
<div class="spine-player-popup-title">Debug</div>
|
||||
<hr>
|
||||
<ul class="spine-player-list">
|
||||
@ -571,7 +649,10 @@
|
||||
makeItem("Points", "points");
|
||||
makeItem("Hulls", "hulls");
|
||||
|
||||
popup.show();
|
||||
settingsButton.classList.add("spine-player-button-icon-settings-selected")
|
||||
popup.show(() => {
|
||||
settingsButton.classList.remove("spine-player-button-icon-settings-selected")
|
||||
});
|
||||
}
|
||||
|
||||
drawFrame (requestNextFrame = true) {
|
||||
@ -617,11 +698,35 @@
|
||||
|
||||
this.skeleton.updateWorldTransform();
|
||||
|
||||
let viewportSize = this.scale(this.config.viewport.width, this.config.viewport.height, this.canvas.width, this.canvas.height);
|
||||
let viewport = {
|
||||
x: this.currentViewport.x - (this.currentViewport.padLeft as number),
|
||||
y: this.currentViewport.y - (this.currentViewport.padBottom as number),
|
||||
width: this.currentViewport.width + (this.currentViewport.padLeft as number) + (this.currentViewport.padRight as number),
|
||||
height: this.currentViewport.height + (this.currentViewport.padBottom as number) + (this.currentViewport.padTop as number)
|
||||
}
|
||||
|
||||
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;
|
||||
let transitionAlpha = ((performance.now() - this.viewportTransitionStart) / 1000) / this.config.viewport.transitionTime;
|
||||
if (this.previousViewport && transitionAlpha < 1) {
|
||||
let oldViewport = {
|
||||
x: this.previousViewport.x - (this.previousViewport.padLeft as number),
|
||||
y: this.previousViewport.y - (this.previousViewport.padBottom as number),
|
||||
width: this.previousViewport.width + (this.previousViewport.padLeft as number) + (this.previousViewport.padRight as number),
|
||||
height: this.previousViewport.height + (this.previousViewport.padBottom as number) + (this.previousViewport.padTop as number)
|
||||
}
|
||||
|
||||
viewport = {
|
||||
x: oldViewport.x + (viewport.x - oldViewport.x) * transitionAlpha,
|
||||
y: oldViewport.y + (viewport.y - oldViewport.y) * transitionAlpha,
|
||||
width: oldViewport.width + (viewport.width - oldViewport.width) * transitionAlpha,
|
||||
height: oldViewport.height + (viewport.height - oldViewport.height) * transitionAlpha
|
||||
}
|
||||
}
|
||||
|
||||
let viewportSize = this.scale(viewport.width, viewport.height, this.canvas.width, this.canvas.height);
|
||||
|
||||
this.sceneRenderer.camera.zoom = viewport.width / viewportSize.x;
|
||||
this.sceneRenderer.camera.position.x = viewport.x + viewport.width / 2;
|
||||
this.sceneRenderer.camera.position.y = viewport.y + viewport.height / 2;
|
||||
|
||||
this.sceneRenderer.begin();
|
||||
|
||||
@ -629,7 +734,7 @@
|
||||
if (this.config.backgroundImage && this.config.backgroundImage.url) {
|
||||
let 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);
|
||||
this.sceneRenderer.drawTexture(bgImage, viewport.x, viewport.y, viewport.width, viewport.height);
|
||||
} else {
|
||||
this.sceneRenderer.drawTexture(bgImage, this.config.backgroundImage.x, this.config.backgroundImage.y, this.config.backgroundImage.width, this.config.backgroundImage.height);
|
||||
}
|
||||
@ -661,6 +766,12 @@
|
||||
}
|
||||
gl.lineWidth(1);
|
||||
|
||||
// Render the viewport bounds
|
||||
if (this.config.viewport.debugRender) {
|
||||
this.sceneRenderer.rect(false, this.currentViewport.x, this.currentViewport.y, this.currentViewport.width, this.currentViewport.height, Color.GREEN);
|
||||
this.sceneRenderer.rect(false, viewport.x, viewport.y, viewport.width, viewport.height, Color.RED);
|
||||
}
|
||||
|
||||
this.sceneRenderer.end();
|
||||
|
||||
this.sceneRenderer.camera.zoom = 0;
|
||||
@ -734,23 +845,27 @@
|
||||
this.skeleton.setSlotsToSetupPose();
|
||||
}
|
||||
|
||||
// Setup viewport after skin is set
|
||||
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
|
||||
// Setup empty viewport if none is given and check
|
||||
// if all animations for which viewports where given
|
||||
// exist.
|
||||
if (!this.config.viewport) {
|
||||
(this.config.viewport as any) = {
|
||||
animations: {},
|
||||
debugRender: false,
|
||||
transitionTime: 0.2
|
||||
}
|
||||
|
||||
this.skeleton.updateWorldTransform();
|
||||
let offset = new spine.Vector2();
|
||||
let 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 (typeof this.config.viewport.debugRender === "undefined") this.config.viewport.debugRender = false;
|
||||
if (typeof this.config.viewport.transitionTime === "undefined") this.config.viewport.transitionTime = 0.2;
|
||||
if (!this.config.viewport.animations) {
|
||||
this.config.viewport.animations = {};
|
||||
} else {
|
||||
Object.getOwnPropertyNames(this.config.viewport.animations).forEach((animation: string) => {
|
||||
if (!skeletonData.findAnimation(animation)) {
|
||||
this.showError(`Error: animation '${animation}' for which a viewport was specified does not exist in skeleton.`);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Setup the animations after viewport, so default bounds don't get messed up.
|
||||
@ -897,7 +1012,7 @@
|
||||
|
||||
if (this.config.animation) {
|
||||
if (!this.animationState.getCurrent(0)) {
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
this.setAnimation(this.config.animation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -907,6 +1022,114 @@
|
||||
this.playButton.classList.remove("spine-player-button-icon-pause");
|
||||
this.playButton.classList.add("spine-player-button-icon-play");
|
||||
}
|
||||
|
||||
private setAnimation (animation: string) {
|
||||
// Determine viewport
|
||||
this.previousViewport = this.currentViewport;
|
||||
let animViewport = this.calculateAnimationViewport(animation);
|
||||
|
||||
// The calculated animation viewport is the base
|
||||
let viewport: Viewport = {
|
||||
x: animViewport.x,
|
||||
y: animViewport.y,
|
||||
width: animViewport.width,
|
||||
height: animViewport.height,
|
||||
padLeft: "10%",
|
||||
padRight: "10%",
|
||||
padTop: "10%",
|
||||
padBottom: "10%"
|
||||
}
|
||||
|
||||
// Override with global viewport settings if they exist
|
||||
let globalViewport = this.config.viewport;
|
||||
if (typeof globalViewport.x !== "undefined" && typeof globalViewport.y !== "undefined" && typeof globalViewport.width !== "undefined" && typeof globalViewport.height !== "undefined") {
|
||||
viewport.x = globalViewport.x;
|
||||
viewport.y = globalViewport.y;
|
||||
viewport.width = globalViewport.width;
|
||||
viewport.height = globalViewport.height;
|
||||
}
|
||||
if (typeof globalViewport.padLeft !== "undefined") viewport.padLeft = globalViewport.padLeft;
|
||||
if (typeof globalViewport.padRight !== "undefined") viewport.padRight = globalViewport.padRight;
|
||||
if (typeof globalViewport.padTop !== "undefined") viewport.padTop = globalViewport.padTop;
|
||||
if (typeof globalViewport.padBottom !== "undefined") viewport.padBottom = globalViewport.padBottom;
|
||||
|
||||
// Override with animation viewport settings given by user for final result.
|
||||
let userAnimViewport = this.config.viewport.animations[animation];
|
||||
if (userAnimViewport) {
|
||||
if (typeof userAnimViewport.x !== "undefined" && typeof userAnimViewport.y !== "undefined" && typeof userAnimViewport.width !== "undefined" && typeof userAnimViewport.height !== "undefined") {
|
||||
viewport.x = userAnimViewport.x;
|
||||
viewport.y = userAnimViewport.y;
|
||||
viewport.width = userAnimViewport.width;
|
||||
viewport.height = userAnimViewport.height;
|
||||
}
|
||||
if (typeof userAnimViewport.padLeft !== "undefined") viewport.padLeft = userAnimViewport.padLeft;
|
||||
if (typeof userAnimViewport.padRight !== "undefined") viewport.padRight = userAnimViewport.padRight;
|
||||
if (typeof userAnimViewport.padTop !== "undefined") viewport.padTop = userAnimViewport.padTop;
|
||||
if (typeof userAnimViewport.padBottom !== "undefined") viewport.padBottom = userAnimViewport.padBottom;
|
||||
}
|
||||
|
||||
// Translate percentage paddings to world units
|
||||
viewport.padLeft = this.percentageToWorldUnit(viewport.width, viewport.padLeft);
|
||||
viewport.padRight = this.percentageToWorldUnit(viewport.width, viewport.padRight);
|
||||
viewport.padBottom = this.percentageToWorldUnit(viewport.height, viewport.padBottom);
|
||||
viewport.padTop = this.percentageToWorldUnit(viewport.height, viewport.padTop);
|
||||
|
||||
// Adjust x, y, width, and height by padding.
|
||||
this.currentViewport = viewport;
|
||||
this.viewportTransitionStart = performance.now();
|
||||
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose();
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
}
|
||||
|
||||
private percentageToWorldUnit(size: number, percentageOrAbsolute: string | number): number {
|
||||
if (typeof percentageOrAbsolute === "string") {
|
||||
return size * parseFloat(percentageOrAbsolute.substr(0, percentageOrAbsolute.length - 1)) / 100;
|
||||
} else {
|
||||
return percentageOrAbsolute;
|
||||
}
|
||||
}
|
||||
|
||||
private calculateAnimationViewport (animationName: string) {
|
||||
let animation = this.skeleton.data.findAnimation(animationName);
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose()
|
||||
this.animationState.setAnimationWith(0, animation, true);
|
||||
|
||||
let steps = 100;
|
||||
let stepTime = animation.duration > 0 ? animation.duration / steps : 0;
|
||||
let minX = 100000000;
|
||||
let maxX = -100000000;
|
||||
let minY = 100000000;
|
||||
let maxY = -100000000;
|
||||
let offset = new spine.Vector2();
|
||||
let size = new spine.Vector2();
|
||||
|
||||
for (var i = 0; i < steps; i++) {
|
||||
this.animationState.update(stepTime);
|
||||
this.animationState.apply(this.skeleton);
|
||||
this.skeleton.updateWorldTransform();
|
||||
this.skeleton.getBounds(offset, size);
|
||||
|
||||
minX = Math.min(offset.x, minX);
|
||||
maxX = Math.max(offset.x + size.x, maxX);
|
||||
minY = Math.min(offset.y, minY);
|
||||
maxY = Math.max(offset.y + size.y, maxY);
|
||||
}
|
||||
|
||||
offset.x = minX;
|
||||
offset.y = minY;
|
||||
size.x = maxX - minX;
|
||||
size.y = maxY - minY;
|
||||
|
||||
return {
|
||||
x: offset.x,
|
||||
y: offset.y,
|
||||
width: size.x,
|
||||
height: size.y
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function isContained(dom: HTMLElement, needle: HTMLElement): boolean {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user