From 7a3ec78638e6c1376c7ed165829d5f767fb539e0 Mon Sep 17 00:00:00 2001 From: badlogic Date: Mon, 17 Dec 2018 17:04:58 +0100 Subject: [PATCH] [ts][player] decreased delay for when mouse leaves player area and controls are hidden. --- spine-ts/build/spine-all.d.ts | 107 ++++ spine-ts/build/spine-all.js | 946 +++++++++++++++++++++++++++++ spine-ts/build/spine-all.js.map | 2 +- spine-ts/build/spine-player.js | 4 +- spine-ts/build/spine-player.js.map | 2 +- spine-ts/player/src/Player.ts | 4 +- spine-ts/tsconfig.json | 6 +- 7 files changed, 1062 insertions(+), 9 deletions(-) diff --git a/spine-ts/build/spine-all.d.ts b/spine-ts/build/spine-all.d.ts index c2dafbe47..2e09dc242 100644 --- a/spine-ts/build/spine-all.d.ts +++ b/spine-ts/build/spine-all.d.ts @@ -1772,3 +1772,110 @@ declare module spine.threejs { static toThreeJsTextureWrap(wrap: TextureWrap): THREE.Wrapping; } } +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; + animation: string; + animations: string[]; + defaultMix: number; + skin: string; + skins: string[]; + controlBones: string[]; + premultipliedAlpha: boolean; + showControls: boolean; + debug: { + bones: boolean; + regions: boolean; + meshes: boolean; + bounds: boolean; + paths: boolean; + clipping: boolean; + points: boolean; + hulls: boolean; + }; + viewport: { + x: number; + y: number; + width: number; + height: number; + padLeft: string | number; + padRight: string | number; + padTop: string | number; + padBottom: string | number; + animations: Map; + debugRender: boolean; + transitionTime: number; + }; + alpha: boolean; + backgroundColor: string; + backgroundImage: { + url: string; + x: number; + y: number; + width: number; + height: number; + }; + fullScreenBackgroundColor: string; + success: (widget: SpinePlayer) => void; + error: (widget: SpinePlayer, msg: string) => void; + } + class SpinePlayer { + private config; + static HOVER_COLOR_INNER: Color; + static HOVER_COLOR_OUTER: Color; + static NON_HOVER_COLOR_INNER: Color; + static NON_HOVER_COLOR_OUTER: Color; + private sceneRenderer; + private dom; + private playerControls; + private canvas; + private timelineSlider; + private playButton; + private skinButton; + private animationButton; + private context; + private loadingScreen; + private assetManager; + private loaded; + private skeleton; + private animationState; + private time; + 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; + private lastPopup; + 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); + } +} diff --git a/spine-ts/build/spine-all.js b/spine-ts/build/spine-all.js index b2144c4cd..d444bf78a 100644 --- a/spine-ts/build/spine-all.js +++ b/spine-ts/build/spine-all.js @@ -10090,4 +10090,950 @@ var spine; threejs.ThreeJsTexture = ThreeJsTexture; })(threejs = spine.threejs || (spine.threejs = {})); })(spine || (spine = {})); +var spine; +(function (spine) { + var Popup = (function () { + function Popup(player, parent, htmlContent) { + this.player = player; + this.dom = createElement("\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t"); + this.dom.innerHTML = htmlContent; + parent.appendChild(this.dom); + } + 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) { + justClicked = false; + return; + } + if (!isContained(_this.dom, event.target)) { + _this.dom.remove(); + window.removeEventListener("click", windowClickListener); + dismissedListener(); + dismissed = true; + } + }; + window.addEventListener("click", windowClickListener); + }; + return Popup; + }()); + var Switch = (function () { + function Switch(text) { + this.text = text; + this.enabled = false; + } + Switch.prototype.render = function () { + var _this = this; + this["switch"] = createElement("\n\t\t\t\t
\n\t\t\t\t\t" + this.text + "\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t"); + this["switch"].addEventListener("click", function () { + _this.setEnabled(!_this.enabled); + if (_this.change) + _this.change(_this.enabled); + }); + return this["switch"]; + }; + Switch.prototype.setEnabled = function (enabled) { + if (enabled) + this["switch"].classList.add("active"); + else + this["switch"].classList.remove("active"); + this.enabled = enabled; + }; + Switch.prototype.isEnabled = function () { + return this.enabled; + }; + return Switch; + }()); + var Slider = (function () { + function Slider(snaps, snapPercentage, big) { + if (snaps === void 0) { snaps = 0; } + if (snapPercentage === void 0) { snapPercentage = 0.1; } + if (big === void 0) { big = false; } + this.snaps = snaps; + this.snapPercentage = snapPercentage; + this.big = big; + } + Slider.prototype.render = function () { + var _this = this; + this.slider = createElement("\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t"); + this.value = findWithClass(this.slider, "spine-player-slider-value")[0]; + this.setValue(0); + var input = new spine.webgl.Input(this.slider); + var dragging = false; + input.addListener({ + down: function (x, y) { + dragging = true; + _this.value.classList.add("hovering"); + }, + up: function (x, y) { + dragging = false; + var percentage = x / _this.slider.clientWidth; + percentage = percentage = Math.max(0, Math.min(percentage, 1)); + _this.setValue(x / _this.slider.clientWidth); + if (_this.change) + _this.change(percentage); + _this.value.classList.remove("hovering"); + }, + moved: function (x, y) { + if (dragging) { + var percentage = x / _this.slider.clientWidth; + percentage = Math.max(0, Math.min(percentage, 1)); + percentage = _this.setValue(x / _this.slider.clientWidth); + if (_this.change) + _this.change(percentage); + } + }, + dragged: function (x, y) { + var percentage = x / _this.slider.clientWidth; + percentage = Math.max(0, Math.min(percentage, 1)); + percentage = _this.setValue(x / _this.slider.clientWidth); + if (_this.change) + _this.change(percentage); + } + }); + return this.slider; + }; + Slider.prototype.setValue = function (percentage) { + percentage = Math.max(0, Math.min(1, percentage)); + if (this.snaps > 0) { + var modulo = percentage % (1 / this.snaps); + if (modulo < (1 / this.snaps) * this.snapPercentage) { + percentage = percentage - modulo; + } + else if (modulo > (1 / this.snaps) - (1 / this.snaps) * this.snapPercentage) { + percentage = percentage - modulo + (1 / this.snaps); + } + percentage = Math.max(0, Math.min(1, percentage)); + } + this.value.style.width = "" + (percentage * 100) + "%"; + return percentage; + }; + return Slider; + }()); + var SpinePlayer = (function () { + function SpinePlayer(parent, config) { + this.config = config; + this.time = new spine.TimeKeeper(); + 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) { + if (!config) + throw new Error("Please pass a configuration to new.spine.SpinePlayer()."); + if (!config.jsonUrl) + throw new Error("Please specify the URL of the skeleton JSON file."); + if (!config.atlasUrl) + throw new Error("Please specify the URL of the atlas file."); + if (!config.alpha) + config.alpha = false; + if (!config.backgroundColor) + config.backgroundColor = "#000000"; + if (!config.fullScreenBackgroundColor) + config.fullScreenBackgroundColor = config.backgroundColor; + if (!config.premultipliedAlpha) + config.premultipliedAlpha = false; + if (!config.success) + config.success = function (widget) { }; + if (!config.error) + config.error = function (widget, msg) { }; + if (!config.debug) + config.debug = { + bones: false, + regions: false, + meshes: false, + bounds: false, + clipping: false, + paths: false, + points: false, + hulls: false + }; + if (!config.debug.bones) + config.debug.bones = false; + if (!config.debug.bounds) + config.debug.bounds = false; + if (!config.debug.clipping) + config.debug.clipping = false; + if (!config.debug.hulls) + config.debug.hulls = false; + if (!config.debug.paths) + config.debug.paths = false; + if (!config.debug.points) + config.debug.points = false; + if (!config.debug.regions) + config.debug.regions = false; + if (!config.debug.meshes) + config.debug.meshes = false; + if (config.animations && config.animation) { + if (config.animations.indexOf(config.animation) < 0) + throw new Error("Default animation '" + config.animation + "' is not contained in the list of selectable animations " + escapeHtml(JSON.stringify(this.config.animations)) + "."); + } + if (config.skins && config.skin) { + if (config.skins.indexOf(config.skin) < 0) + throw new Error("Default skin '" + config.skin + "' is not contained in the list of selectable skins " + escapeHtml(JSON.stringify(this.config.skins)) + "."); + } + if (!config.controlBones) + config.controlBones = []; + if (typeof config.showControls === "undefined") + config.showControls = true; + if (typeof config.defaultMix === "undefined") + config.defaultMix = 0.25; + return config; + }; + SpinePlayer.prototype.showError = function (error) { + var errorDom = findWithClass(this.dom, "spine-player-error")[0]; + errorDom.classList.remove("spine-player-hidden"); + errorDom.innerHTML = "

" + error + "

"; + this.config.error(this, error); + }; + SpinePlayer.prototype.render = function () { + var _this = this; + var config = this.config; + var dom = this.dom = createElement("\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t"); + try { + this.config = this.validateConfig(config); + } + catch (e) { + this.showError(e); + return dom; + } + try { + this.canvas = findWithClass(dom, "spine-player-canvas")[0]; + var webglConfig = { alpha: config.alpha }; + this.context = new spine.webgl.ManagedWebGLRenderingContext(this.canvas, webglConfig); + this.sceneRenderer = new spine.webgl.SceneRenderer(this.canvas, this.context, true); + this.loadingScreen = new spine.webgl.LoadingScreen(this.sceneRenderer); + } + catch (e) { + this.showError("Sorry, your browser does not support WebGL.

Please use the latest version of Firefox, Chrome, Edge, or Safari."); + return dom; + } + this.assetManager = new spine.webgl.AssetManager(this.context); + this.assetManager.loadText(config.jsonUrl); + this.assetManager.loadTextureAtlas(config.atlasUrl); + if (config.backgroundImage && config.backgroundImage.url) + this.assetManager.loadTexture(config.backgroundImage.url); + requestAnimationFrame(function () { return _this.drawFrame(); }); + this.playerControls = findWithClass(dom, "spine-player-controls")[0]; + var timeline = findWithClass(dom, "spine-player-timeline")[0]; + this.timelineSlider = new Slider(); + timeline.appendChild(this.timelineSlider.render()); + this.playButton = findWithId(dom, "spine-player-button-play-pause")[0]; + var speedButton = findWithId(dom, "spine-player-button-speed")[0]; + this.animationButton = findWithId(dom, "spine-player-button-animation")[0]; + this.skinButton = findWithId(dom, "spine-player-button-skin")[0]; + var settingsButton = findWithId(dom, "spine-player-button-settings")[0]; + var fullscreenButton = findWithId(dom, "spine-player-button-fullscreen")[0]; + var logoButton = findWithId(dom, "spine-player-button-logo")[0]; + this.playButton.onclick = function () { + if (_this.paused) + _this.play(); + else + _this.pause(); + }; + speedButton.onclick = function () { + _this.showSpeedDialog(speedButton); + }; + this.animationButton.onclick = function () { + _this.showAnimationsDialog(_this.animationButton); + }; + this.skinButton.onclick = function () { + _this.showSkinsDialog(_this.skinButton); + }; + settingsButton.onclick = function () { + _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(); + 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; + var player = dom; + if (player.requestFullscreen) + player.requestFullscreen(); + else if (player.webkitRequestFullScreen) + player.webkitRequestFullScreen(); + else if (player.mozRequestFullScreen) + player.mozRequestFullScreen(); + else if (player.msRequestFullscreen) + player.msRequestFullscreen(); + } + }; + logoButton.onclick = function () { + window.open("http://esotericsoftware.com"); + }; + window.onresize = function () { + _this.drawFrame(false); + }; + return dom; + }; + SpinePlayer.prototype.showSpeedDialog = function (speedButton) { + var _this = this; + if (this.lastPopup) + this.lastPopup.dom.remove(); + if (this.lastPopup && findWithClass(this.lastPopup.dom, "spine-player-popup-title")[0].textContent == "Speed") { + this.lastPopup = null; + speedButton.classList.remove("spine-player-button-icon-speed-selected"); + return; + } + var popup = new Popup(this.dom, this.playerControls, "\n\t\t\t\t
Speed
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
0.1x
\n\t\t\t\t\t\t\t
1x
\n\t\t\t\t\t\t\t
2x
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\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()); + slider.setValue(this.speed / 2); + slider.change = function (percentage) { + _this.speed = percentage * 2; + }; + speedButton.classList.add("spine-player-button-icon-speed-selected"); + popup.show(function () { + speedButton.classList.remove("spine-player-button-icon-speed-selected"); + }); + this.lastPopup = popup; + }; + SpinePlayer.prototype.showAnimationsDialog = function (animationsButton) { + var _this = this; + if (this.lastPopup) + this.lastPopup.dom.remove(); + if (this.lastPopup && findWithClass(this.lastPopup.dom, "spine-player-popup-title")[0].textContent == "Animations") { + this.lastPopup = null; + animationsButton.classList.remove("spine-player-button-icon-animations-selected"); + return; + } + if (!this.skeleton || this.skeleton.data.animations.length == 0) + return; + var popup = new Popup(this.dom, this.playerControls, "\n\t\t\t\t
Animations
\n\t\t\t\t
\n\t\t\t\t\n\t\t\t"); + var rows = findWithClass(popup.dom, "spine-player-list")[0]; + this.skeleton.data.animations.forEach(function (animation) { + if (_this.config.animations && _this.config.animations.indexOf(animation.name) < 0) { + return; + } + var row = createElement("\n\t\t\t\t\t
  • \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
  • \n\t\t\t\t"); + if (animation.name == _this.config.animation) + row.classList.add("selected"); + findWithClass(row, "selectable-text")[0].innerText = animation.name; + rows.appendChild(row); + row.onclick = function () { + removeClass(rows.children, "selected"); + row.classList.add("selected"); + _this.config.animation = animation.name; + _this.playTime = 0; + _this.setAnimation(animation.name); + }; + }); + animationsButton.classList.add("spine-player-button-icon-animations-selected"); + popup.show(function () { + animationsButton.classList.remove("spine-player-button-icon-animations-selected"); + }); + this.lastPopup = popup; + }; + SpinePlayer.prototype.showSkinsDialog = function (skinButton) { + var _this = this; + if (this.lastPopup) + this.lastPopup.dom.remove(); + if (this.lastPopup && findWithClass(this.lastPopup.dom, "spine-player-popup-title")[0].textContent == "Skins") { + this.lastPopup = null; + skinButton.classList.remove("spine-player-button-icon-skins-selected"); + return; + } + if (!this.skeleton || this.skeleton.data.animations.length == 0) + return; + var popup = new Popup(this.dom, this.playerControls, "\n\t\t\t\t
    Skins
    \n\t\t\t\t
    \n\t\t\t\t\n\t\t\t"); + var rows = findWithClass(popup.dom, "spine-player-list")[0]; + this.skeleton.data.skins.forEach(function (skin) { + if (_this.config.skins && _this.config.skins.indexOf(skin.name) < 0) { + return; + } + var row = createElement("\n\t\t\t\t\t
  • \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t
  • \n\t\t\t\t"); + if (skin.name == _this.config.skin) + row.classList.add("selected"); + findWithClass(row, "selectable-text")[0].innerText = skin.name; + rows.appendChild(row); + row.onclick = function () { + removeClass(rows.children, "selected"); + row.classList.add("selected"); + _this.config.skin = skin.name; + _this.skeleton.setSkinByName(_this.config.skin); + _this.skeleton.setSlotsToSetupPose(); + }; + }); + skinButton.classList.add("spine-player-button-icon-skins-selected"); + popup.show(function () { + skinButton.classList.remove("spine-player-button-icon-skins-selected"); + }); + this.lastPopup = popup; + }; + SpinePlayer.prototype.showSettingsDialog = function (settingsButton) { + var _this = this; + if (this.lastPopup) + this.lastPopup.dom.remove(); + if (this.lastPopup && findWithClass(this.lastPopup.dom, "spine-player-popup-title")[0].textContent == "Debug") { + this.lastPopup = null; + settingsButton.classList.remove("spine-player-button-icon-settings-selected"); + return; + } + if (!this.skeleton || this.skeleton.data.animations.length == 0) + return; + var popup = new Popup(this.dom, this.playerControls, "\n\t\t\t\t
    Debug
    \n\t\t\t\t
    \n\t\t\t\t