diff --git a/main.html b/main.html
index e56a543..af22195 100644
--- a/main.html
+++ b/main.html
@@ -255,6 +255,20 @@
Mobile Device Detected
data-name="Right" fill="none" id="Right-2" points="7.9 12.3 12 16.3 16.1 12.3" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
save
+
diff --git a/main.js b/main.js
index 39450ca..fc8bb79 100644
--- a/main.js
+++ b/main.js
@@ -4,6 +4,9 @@ const dropLoader = PIXI.Assets, cont = new PIXI.Container();
const SML0 = "sml_cloth0", SML1 = "sml_cloth1", BIG0 = "big_cloth0", BIG1 = "big_cloth1";
const urlParams = new URLSearchParams(window.location.search);
+// State
+let isContinuousShootingEnabled = false
+
const idolMap = new Map();
const spineMap = new Map();
@@ -83,7 +86,7 @@ async function renderByDrop(dataTexture) {
const spineAtlasLoader = new PIXI.spine.core.AtlasAttachmentLoader(spineAtlas);
const spineJsonParser = new PIXI.spine.core.SkeletonJson(spineAtlasLoader);
const spineData = spineJsonParser.readSkeletonData(rawJson);
- setupAnimationList(spineData);
+ await setupAnimationList(spineData);
}
function toastInit() {
@@ -98,6 +101,11 @@ function toastInit() {
}
}
+function tooltipInit() {
+ const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
+ const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
+}
+
function toMobileUI() {
window.location.href = "https://mspine.shinycolors.moe";
}
@@ -115,6 +123,7 @@ async function init() {
}
toastInit();
+ tooltipInit();
const canvas = document.getElementById("canvas"), resetBtn = document.getElementById("resetAnimation");
app = new PIXI.Application({
@@ -134,13 +143,19 @@ async function init() {
resetAllAnimation();
}
+ const continuousShootingModeSwitch = document.getElementById("continuousShootingModeSwitch")
+ continuousShootingModeSwitch.addEventListener("change", (event) => {
+ isContinuousShootingEnabled = event.target.checked
+ // console.info(`enableContinuousShooting:${isContinuousShootingEnabled}`)
+ })
+
fetch("https://api.shinycolors.moe/spine/idollist").then(async (response) => {
const idolInfo = await response.json();
const idolInfoMap = new Map();
idolInfo.forEach((element) => {
idolInfoMap.set(element.idolId, element);
});
- setupIdolList(idolInfoMap);
+ await setupIdolList(idolInfoMap);
});
_hello();
@@ -158,7 +173,7 @@ function _hello() {
console.log(...log);
}
-function setupIdolList(idolInfo) {
+async function setupIdolList(idolInfo) {
const idolList = document.getElementById("idolList");
let idolId = urlParams.has("idolId") ? Number(urlParams.get("idolId")) : 1,
idolName = idolInfo.get(idolId).idolName;
@@ -174,13 +189,13 @@ function setupIdolList(idolInfo) {
idolList.appendChild(option);
});
- idolList.onchange = () => {
+ idolList.onchange = async () => {
idolId = idolList.value;
idolName = idolInfo.get(Number(idolId)).idolName;
- testAndLoadDress(idolId, idolName);
+ await testAndLoadDress(idolId, idolName);
};
- testAndLoadDress(idolId, idolName);
+ await testAndLoadDress(idolId, idolName);
}
/*
function testAndLoadPreset(idolId) {
@@ -198,27 +213,27 @@ function setupPreset(presetList) {
}
-function testAndLoadDress(idolId, idolName) {
+async function testAndLoadDress(idolId, idolName) {
if (!idolMap.has(idolName)) {
if (idolId == 0) {
fetch(`https://cf-static.shinycolors.moe/others/hazuki.json`).then(async (response) => {
idolMap.set(idolName, await response.json());
- setupDressList(idolMap.get(idolName));
+ await setupDressList(idolMap.get(idolName));
});
}
else {
fetch(`https://api.shinycolors.moe/spine/dressList?idolId=${idolId}`).then(async (response) => {
idolMap.set(idolName, await response.json());
- setupDressList(idolMap.get(idolName));
+ await setupDressList(idolMap.get(idolName));
});
}
}
else {
- setupDressList(idolMap.get(idolName));
+ await setupDressList(idolMap.get(idolName));
}
}
-function setupDressList(idolDressList) {
+async function setupDressList(idolDressList) {
const dressList = document.getElementById("dressList");
dressList.innerHTML = "";
@@ -258,15 +273,15 @@ function setupDressList(idolDressList) {
});
dressList.appendChild(optGroup);
- dressList.onchange = () => {
+ dressList.onchange = async () => {
arrayOrder = dressList.value;
- setupTypeList(idolDressList[arrayOrder]);
+ await setupTypeList(idolDressList[arrayOrder]);
};
- setupTypeList(idolDressList[arrayOrder]);
+ await setupTypeList(idolDressList[arrayOrder]);
}
-function setupTypeList(dressObj) {
+async function setupTypeList(dressObj) {
const typeList = document.getElementById("typeList");
let dressType;
typeList.innerHTML = "";
@@ -351,50 +366,50 @@ function setupTypeList(dressObj) {
}
}
- typeList.onchange = () => {
+ typeList.onchange = async () => {
const dressList = document.getElementById("dressList");
dressType = typeList.value;
if (dressObj.idolId == 0) {
- testAndLoadAnimation(dressList.options[dressList.selectedIndex].getAttribute("path"), dressType, true);
+ await testAndLoadAnimation(dressList.options[dressList.selectedIndex].getAttribute("path"), dressType, true);
}
else {
- testAndLoadAnimation(dressList.options[dressList.selectedIndex].getAttribute("enzaId"), dressType);
+ await testAndLoadAnimation(dressList.options[dressList.selectedIndex].getAttribute("enzaId"), dressType);
}
};
if (dressObj.idolId == 0) {
- testAndLoadAnimation(dressObj.path, dressType, true);
+ await testAndLoadAnimation(dressObj.path, dressType, true);
}
else {
- testAndLoadAnimation(dressObj.enzaId, dressType);
+ await testAndLoadAnimation(dressObj.enzaId, dressType);
}
}
-function testAndLoadAnimation(enzaId, type, flag = false) {
+async function testAndLoadAnimation(enzaId, type, flag = false) {
if (!spineMap.has(`${enzaId}/${type}`)) {
if (flag) {
- PIXI.Assets.load(`https://cf-static.shinycolors.moe/spine/sub_characters/${migrateMap[type]}/${enzaId}`).then((resource) => {
+ PIXI.Assets.load(`https://cf-static.shinycolors.moe/spine/sub_characters/${migrateMap[type]}/${enzaId}`).then(async (resource) => {
const waifu = resource.spineData;
spineMap.set(`${enzaId}/${type}`, waifu);
- setupAnimationList(waifu);
+ await setupAnimationList(waifu);
});
}
else {
- PIXI.Assets.load(`https://cf-static.shinycolors.moe/spine/idols/${migrateMap[type]}/${enzaId}/data.json`).then((resource) => {
+ PIXI.Assets.load(`https://cf-static.shinycolors.moe/spine/idols/${migrateMap[type]}/${enzaId}/data.json`).then(async (resource) => {
const waifu = resource.spineData;
spineMap.set(`${enzaId}/${type}`, waifu);
- setupAnimationList(waifu);
+ await setupAnimationList(waifu);
});
}
}
else {
- setupAnimationList(spineMap.get(`${enzaId}/${type}`));
+ await setupAnimationList(spineMap.get(`${enzaId}/${type}`));
}
}
-function setupAnimationList(spineData) {
+async function setupAnimationList(spineData) {
const animationList = document.getElementById("divAnimationBody");
animationList.innerHTML = "";
@@ -447,7 +462,7 @@ function setupAnimationList(spineData) {
currentSpine.state.setAnimation(0, currentSpine.spineData.animations[0].name, true);
}
- renderToStage(currentSpine);
+ await renderToStage(currentSpine);
}
function animationOnChange(theInput, trackNo, currentSpine) {
@@ -470,8 +485,13 @@ function blobToBase64(blob) {
reader.readAsDataURL(blob);
});
}
-
-function renderToStage(currentSpine) {
+const clearState = (spine) => {
+ spine.state.clearTracks();
+ spine.skeleton.setToSetupPose();
+ spine.lastTime = null;
+};
+async function renderToStage(currentSpine) {
+ if (isContinuousShootingEnabled) { clearState(currentSpine) }
cont.removeChild(cont.children[0]);
cont.addChild(currentSpine);
@@ -497,6 +517,8 @@ function renderToStage(currentSpine) {
cont.scale.set(scale);
cont.pivot.set(contLocalBound.width / 2, contLocalBound.height / 2);
cont.position.set(app.view.width / 2, app.view.height / 2);
+
+ if (isContinuousShootingEnabled) { await saveImage(); }
}
function resetAllAnimation() {