From fca2f0c7af99dc8aceba6a6f0af62cc5efc77a0d Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 26 Nov 2019 18:12:13 +0100 Subject: [PATCH] [ts] web player generator. --- .../generator/embedding-generator.html | 157 ++ .../example/generator/embedding-generator.js | 401 ++++ spine-ts/player/example/generator/jscolor.js | 1855 +++++++++++++++++ 3 files changed, 2413 insertions(+) create mode 100644 spine-ts/player/example/generator/embedding-generator.html create mode 100644 spine-ts/player/example/generator/embedding-generator.js create mode 100644 spine-ts/player/example/generator/jscolor.js diff --git a/spine-ts/player/example/generator/embedding-generator.html b/spine-ts/player/example/generator/embedding-generator.html new file mode 100644 index 000000000..29e82c7d7 --- /dev/null +++ b/spine-ts/player/example/generator/embedding-generator.html @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + +
+ Choose .skel/.json, .atlas, and .png files, or drop them here. + +
+
+
+
+
+
+ General + Animations + Viewports + Skins + Debug +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Show controls
Premultiplied alpha
Canvas alpha
Background color
Fullscreen background color
Background image + +
+
+
+ Animations +
+
+ Viewports +
+
+ Skins +
+
+ Debug +
+
+
+ + \ No newline at end of file diff --git a/spine-ts/player/example/generator/embedding-generator.js b/spine-ts/player/example/generator/embedding-generator.js new file mode 100644 index 000000000..5f5d451cd --- /dev/null +++ b/spine-ts/player/example/generator/embedding-generator.js @@ -0,0 +1,401 @@ +window.addEventListener("load", function(event) { + setupDropZone(); +}); + +if (!String.prototype.endsWith) { + String.prototype.endsWith = function(search, this_len) { + if (this_len === undefined || this_len > this.length) { + this_len = this.length; + } + return this.substring(this_len - search.length, this_len) === search; + }; +} + +var appState = { + dataUrls: null, + jsonFile: null, + skelFile: null, + atlasFile: null, + minorVersion: null, + majorVersion: null, + player: null +} + +function loadFiles(files) { + var skels = 0; + var skelFile = null; + var jsons = 0; + var jsonFile = null; + var atlases = 0; + var atlasFile = null; + var pngs = 0; + + for (var i = 0; i < files.length; i++) { + var file = files[i].name.toLowerCase(); + if (file.endsWith(".skel")) { + skels++; + skelFile = file; + } + if (file.endsWith(".json")) { + jsons++; + jsonFile = file; + } + if (file.endsWith(".atlas")) { + atlases++; + atlasFile = file; + } + if (file.endsWith(".png")) pngs++; + } + + if ((skels == 0 && jsons == 0) || (skels != 0 && jsons != 0) || skels > 1 || jsons > 1) { + showError("Please specify a single .skel or .json file."); + return; + } + + if (atlases != 1) { + showError("Please specify a single .atlas file."); + return; + } + + var filesToLoad = files.length; + var dataUrls = {}; + for (var i = 0; i < files.length; i++) { + var file = files[i]; + var reader = new FileReader(); + reader.onload = function(file) { + return function(dataUrl) { + console.log("Loaded " + file.name); + dataUrls[file.name] = dataUrl.target.result; + filesToLoad--; + if (filesToLoad == 0) { + setupPlayer(dataUrls, jsonFile, skelFile, atlasFile); + } + }; + }(file); + reader.onerror = function () { + showError("Sorry, couldn't load all files."); + } + reader.readAsDataURL(file); + } +} + +function setupPlayer(dataUrls, jsonFile, skelFile, atlasFile) { + var version = getSkeletonVersion(dataUrls, jsonFile, skelFile); + var major = parseInt(version.split("\.")[0]); + var minor = parseInt(version.split("\.")[1]); + + appState.dataUrls = dataUrls; + appState.jsonFile = jsonFile; + appState.skelFile = skelFile; + appState.atlasFile = atlasFile; + appState.majorVersion = major; + appState.minorVersion = minor; + + if (major == 3 && minor < 8) { + showError("Couldn't load script for Spine version " + version + ". Only skeletons with version >= 3.8 are supported."); + return; + } + + var cssUrl = "https://esotericsoftware.com/files/spine-player/" + major + "." + minor + "/spine-player.css"; + spine = null; + loadCSS(cssUrl, function () { + var playerUrl = "https://esotericsoftware.com/files/spine-player/" + major + "." + minor + "/spine-player.js"; + loadJavaScript(playerUrl, function() { + document.getElementById("sp_generator_editor").classList.remove("sp_generator_hidden"); + document.getElementById("sp_generator_drop_zone").classList.add("sp_generator_hidden"); + var player = document.getElementById("sp_generator_player"); + player.innerHTML = ""; + + var config = { + jsonUrl: jsonFile, + skelUrl: skelFile, + atlasUrl: atlasFile, + rawDataURIs: dataUrls, + success: setupConfigUI, + alpha: true // needed so we can emulate shizzle + }; + + appState.player = new spine.SpinePlayer(player, config); + + }, function() { + showError("Couldn't load script for Spine version " + version + ". Only skeletons with version 3.8+ are supported."); + }); + }, function () { + showError("Couldn't load CSS for Spine version " + version + ". Only skeletons with version 3.8+ are supported."); + }); +} + +function setupConfigUI() { + // Setup tabs + var tabs = document.getElementsByClassName("sp_generator_tabs")[0]; + var children = tabs.getElementsByTagName("span"); + for (var i = 0; i < children.length; i++) { + (function (tab) { + tab.onclick = function () { + var panelId = tab.getAttribute("data-tab"); + var panels = document.getElementById("sp_generator_config").getElementsByClassName("sp_generator_panel"); + for (var i = 0; i < panels.length; i++) { + var panel = panels[i]; + if (panelId == panel.getAttribute("id")) { + tab.classList.add("sp_generator_selected_tab"); + panel.classList.remove("sp_generator_hidden"); + } else { + tab.classList.remove("sp_generator_selected_tab"); + panel.classList.add("sp_generator_hidden"); + } + } + } + })(children[i]); + } + + // Fill general tab + var showControls = document.getElementById("sp_generator_show_controls"); + showControls.onchange = function () { + appState.player.config.showControls = showControls.checked; + }; + var canvasAlpha = document.getElementById("sp_generator_canvas_alpha"); + canvasAlpha.onchange = function () { + var re = /[0-9A-Fa-f]{2}/g; + if (canvasAlpha.value.length > 2 || !re.test(canvasAlpha.value)) + canvasAlpha.value = "FF"; + else + canvasAlpha.value = canvasAlpha.value.toUpperCase(); + var alpha = Number.parseInt(canvasAlpha.value, 16); + appState.player.config.alpha = alpha != 0xff; + appState.player.config.backgroundColor = document.getElementById("sp_generator_background").value + canvasAlpha.value; + } + var premultipliedAlpha = document.getElementById("sp_generator_premultiplied_alpha"); + var premultipliedAlpha = document.getElementById("sp_generator_premultiplied_alpha"); + premultipliedAlpha.onchange = function () { + appState.player.config.premultipliedAlpha = premultipliedAlpha.checked; + } + var backgroundImage = document.getElementById("sp_generator_background_image"); + backgroundImage.innerHTML = ""; + var noneImage = document.createElement("option"); + noneImage.value = "none"; + noneImage.innerText = "None"; + noneImage.selected = true; + backgroundImage.append(noneImage); + for(var data in appState.dataUrls) { + if (data.toLowerCase().endsWith(".png")) { + var image = document.createElement("option"); + image.value = data; + image.innerText = data; + backgroundImage.append(image); + } + } + backgroundImage.onchange = function() { + var imageUrl = backgroundImage.value; + if (imageUrl != "none" && !appState.player.assetManager.get(imageUrl)) { + appState.player.assetManager.loadTexture(imageUrl); + } + + if (appState.player.config.backgroundImage) { + appState.player.config.backgroundImage.url = imageUrl != "none" ? imageUrl: null; + } else { + appState.player.config.backgroundImage = { + url: imageUrl != "none" ? imageUrl : null + } + } + } + + // Fill animations tab + + // Fill viewports tab + + // Fill skins tab + + // Fill debug tab +} + +function changeBackgroundColor(background) { + appState.player.config.backgroundColor = background.valueElement.value + document.getElementById("sp_generator_canvas_alpha").value; +} + +function changeFullscreenBackgroundColor(background) { + appState.player.config.fullScreenBackgroundColor = background.valueElement.value; +} + +function getSkeletonVersion(dataUrls, jsonFile, skelFile) { + if (jsonFile) { + var json = JSON.parse(atob(dataUrls[jsonFile].split(',')[1])); + return json.skeleton.spine; + } else { + var bytes = atob(dataUrls[skelFile].split(',')[1]); + var array = new Uint8Array(new ArrayBuffer(bytes.length)); + for (var i = 0; i < bytes.length; i++) { + array[i] = bytes.charCodeAt(i); + } + + var input = new BinaryInput(array); + input.readString(); + var version = input.readString(); + return version;x + } +} + +function loadJavaScript(url, success, error) { + var script = document.createElement('script'); + script.setAttribute('src', url); + script.setAttribute('type', 'text/javascript'); + script.onload = success; + script.onerror = error; + document.getElementsByTagName("head")[0].appendChild(script); +}; + +function loadCSS(url, success, error) { + var script = document.createElement('link'); + script.setAttribute('href', url); + script.setAttribute('rel', 'stylesheet'); + script.onload = success; + script.onerror = error; + document.getElementsByTagName("head")[0].appendChild(script); + }; + +function showError(error) { + alert(error); +} + +function setupDropZone() { + var fileButton = document.getElementById("sp_generator_file_button"); + var dropZone = document.getElementById("sp_generator_drop_zone"); + dropZone.onclick = function() { + fileButton.click(); + }; + dropZone.addEventListener("dragenter", function (event) { + event.stopPropagation(); + event.preventDefault(); + }, false); + dropZone.addEventListener("dragover", function (event) { + event.stopPropagation(); + event.preventDefault(); + }, false); + dropZone.addEventListener("drop", function (event) { + event.stopPropagation(); + event.preventDefault(); + + loadFiles(event.dataTransfer.files); + }, false); + + + fileButton.onchange = function () { + loadFiles(fileButton.files); + fileButton.value = ""; + }; +} + +function generateScript(jsonFile, skelFile, atlasFile, dataUrls) { + var shortVersion = major + "." + minor; + var scriptCode = + '