sa2kit 1.6.14 → 1.6.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audioDetection/index.js.map +1 -1
- package/dist/audioDetection/index.mjs.map +1 -1
- package/dist/auth/index.js +3 -3
- package/dist/auth/index.mjs +1 -1
- package/dist/{chunk-GGGTJETD.mjs → chunk-3WOAPLEG.mjs} +3 -3
- package/dist/{chunk-GGGTJETD.mjs.map → chunk-3WOAPLEG.mjs.map} +1 -1
- package/dist/{chunk-5D7ZFZIM.js → chunk-5YQ5B7IZ.js} +2 -2
- package/dist/{chunk-5D7ZFZIM.js.map → chunk-5YQ5B7IZ.js.map} +1 -1
- package/dist/{chunk-VZFHU553.mjs → chunk-6MQUBPKB.mjs} +2 -2
- package/dist/{chunk-VZFHU553.mjs.map → chunk-6MQUBPKB.mjs.map} +1 -1
- package/dist/{chunk-LFM5QSFW.js → chunk-A3UP56MS.js} +2 -2
- package/dist/{chunk-LFM5QSFW.js.map → chunk-A3UP56MS.js.map} +1 -1
- package/dist/{chunk-66EHKQVS.js → chunk-CLKKZSPZ.js} +2 -2
- package/dist/{chunk-66EHKQVS.js.map → chunk-CLKKZSPZ.js.map} +1 -1
- package/dist/{chunk-MRGFYQTC.mjs → chunk-CNTILN5J.mjs} +2 -2
- package/dist/{chunk-MRGFYQTC.mjs.map → chunk-CNTILN5J.mjs.map} +1 -1
- package/dist/{chunk-UUM5BIOU.js → chunk-E7RGBAYJ.js} +7 -7
- package/dist/{chunk-UUM5BIOU.js.map → chunk-E7RGBAYJ.js.map} +1 -1
- package/dist/{chunk-TGL6BATG.mjs → chunk-MW4BCIZC.mjs} +2 -2
- package/dist/{chunk-TGL6BATG.mjs.map → chunk-MW4BCIZC.mjs.map} +1 -1
- package/dist/imageCrop/index.js.map +1 -1
- package/dist/imageCrop/index.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/mmd/index.d.mts +169 -5
- package/dist/mmd/index.d.ts +169 -5
- package/dist/mmd/index.js +463 -67
- package/dist/mmd/index.js.map +1 -1
- package/dist/mmd/index.mjs +463 -69
- package/dist/mmd/index.mjs.map +1 -1
- package/dist/music/index.js +16 -16
- package/dist/music/index.mjs +2 -2
- package/dist/music/server/index.js +8 -8
- package/dist/music/server/index.mjs +1 -1
- package/dist/testYourself/admin/index.js +3 -3
- package/dist/testYourself/admin/index.mjs +1 -1
- package/dist/testYourself/index.js +7 -7
- package/dist/testYourself/index.js.map +1 -1
- package/dist/testYourself/index.mjs +2 -2
- package/dist/testYourself/index.mjs.map +1 -1
- package/package.json +17 -19
package/dist/mmd/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
3
|
+
var chunkE7RGBAYJ_js = require('../chunk-E7RGBAYJ.js');
|
|
4
|
+
require('../chunk-A3UP56MS.js');
|
|
5
5
|
var chunkJZXJQMVE_js = require('../chunk-JZXJQMVE.js');
|
|
6
6
|
require('../chunk-DGUM43GV.js');
|
|
7
7
|
var React10 = require('react');
|
|
@@ -1177,6 +1177,7 @@ var MMDPlayerBase = React10.forwardRef((props, ref) => {
|
|
|
1177
1177
|
const audioRef = React10.useRef(null);
|
|
1178
1178
|
const audioListenerRef = React10.useRef(null);
|
|
1179
1179
|
const audioLoaderRef = React10.useRef(new THREE2__namespace.AudioLoader());
|
|
1180
|
+
const [isAudioSystemReady, setIsAudioSystemReady] = React10.useState(false);
|
|
1180
1181
|
const latestCallbacks = React10.useRef({ onPlay, onPause, onEnded, onTimeUpdate });
|
|
1181
1182
|
React10.useEffect(() => {
|
|
1182
1183
|
latestCallbacks.current = { onPlay, onPause, onEnded, onTimeUpdate };
|
|
@@ -1194,6 +1195,10 @@ var MMDPlayerBase = React10.forwardRef((props, ref) => {
|
|
|
1194
1195
|
React10.useImperativeHandle(ref, () => ({
|
|
1195
1196
|
play: () => {
|
|
1196
1197
|
if (!isReadyRef.current) return;
|
|
1198
|
+
if (isPlayingRef.current) {
|
|
1199
|
+
console.log("[MMDPlayerBase] play() called but already playing, skipping");
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1197
1202
|
console.log("[MMDPlayerBase] play() called, audioRef:", !!audioRef.current, "isPlaying:", audioRef.current?.isPlaying);
|
|
1198
1203
|
isPlayingRef.current = true;
|
|
1199
1204
|
if (!clockRef.current.running) clockRef.current.start();
|
|
@@ -1436,6 +1441,7 @@ var MMDPlayerBase = React10.forwardRef((props, ref) => {
|
|
|
1436
1441
|
afterglow: 2
|
|
1437
1442
|
});
|
|
1438
1443
|
helperRef.current = helper;
|
|
1444
|
+
setIsAudioSystemReady(true);
|
|
1439
1445
|
const loadModelPromise = new Promise((resolve, reject) => {
|
|
1440
1446
|
if (resources.motionPath) {
|
|
1441
1447
|
loader.loadWithAnimation(
|
|
@@ -1853,6 +1859,7 @@ ${errorMessage}
|
|
|
1853
1859
|
console.warn("[MMDPlayerBase] Error cleaning up AnimationHelper:", e);
|
|
1854
1860
|
}
|
|
1855
1861
|
helperRef.current = null;
|
|
1862
|
+
setIsAudioSystemReady(false);
|
|
1856
1863
|
}
|
|
1857
1864
|
animationClipRef.current = null;
|
|
1858
1865
|
if (axesHelperRef.current) {
|
|
@@ -2009,9 +2016,19 @@ ${errorMessage}
|
|
|
2009
2016
|
};
|
|
2010
2017
|
}, [resources.modelPath, resources.motionPath, resources.stageModelPath, stage.enablePhysics, stage.physicsPath]);
|
|
2011
2018
|
React10.useEffect(() => {
|
|
2012
|
-
if (!audioListenerRef.current || !helperRef.current || !resources.audioPath)
|
|
2019
|
+
if (!isAudioSystemReady || !audioListenerRef.current || !helperRef.current || !resources.audioPath) {
|
|
2020
|
+
console.log("[MMDPlayerBase] \u{1F3B5} Audio loading skipped:", {
|
|
2021
|
+
isAudioSystemReady,
|
|
2022
|
+
hasListener: !!audioListenerRef.current,
|
|
2023
|
+
hasHelper: !!helperRef.current,
|
|
2024
|
+
audioPath: resources.audioPath
|
|
2025
|
+
});
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2013
2028
|
const listener = audioListenerRef.current;
|
|
2014
2029
|
const helper = helperRef.current;
|
|
2030
|
+
let retryTimer = null;
|
|
2031
|
+
console.log("[MMDPlayerBase] \u{1F3B5} Starting audio load for:", resources.audioPath);
|
|
2015
2032
|
if (audioRef.current) {
|
|
2016
2033
|
const oldSound = audioRef.current;
|
|
2017
2034
|
if (oldSound.isPlaying) oldSound.stop();
|
|
@@ -2031,14 +2048,29 @@ ${errorMessage}
|
|
|
2031
2048
|
delay: 0,
|
|
2032
2049
|
duration: buffer.duration
|
|
2033
2050
|
});
|
|
2051
|
+
console.log("[MMDPlayerBase] \u{1F3B5} Audio loaded, isPlayingRef:", isPlayingRef.current, "autoPlay:", autoPlay, "isReadyRef:", isReadyRef.current);
|
|
2034
2052
|
if (isPlayingRef.current) {
|
|
2053
|
+
console.log("[MMDPlayerBase] \u{1F3B5} Playing audio immediately (isPlayingRef=true)");
|
|
2035
2054
|
sound.play();
|
|
2055
|
+
} else if (autoPlay) {
|
|
2056
|
+
console.log("[MMDPlayerBase] \u{1F3B5} Audio loaded before autoPlay triggered, waiting for play state...");
|
|
2057
|
+
retryTimer = setTimeout(() => {
|
|
2058
|
+
if (isPlayingRef.current && audioRef.current && !audioRef.current.isPlaying) {
|
|
2059
|
+
console.log("[MMDPlayerBase] \u{1F3B5} Playing audio after delay (autoPlay=true)");
|
|
2060
|
+
audioRef.current.play();
|
|
2061
|
+
}
|
|
2062
|
+
}, 150);
|
|
2036
2063
|
}
|
|
2037
2064
|
},
|
|
2038
2065
|
void 0,
|
|
2039
2066
|
(err) => console.error("[MMDPlayerBase] Failed to load audio track:", err)
|
|
2040
2067
|
);
|
|
2041
|
-
|
|
2068
|
+
return () => {
|
|
2069
|
+
if (retryTimer) {
|
|
2070
|
+
clearTimeout(retryTimer);
|
|
2071
|
+
}
|
|
2072
|
+
};
|
|
2073
|
+
}, [resources.audioPath, volume, autoPlay, isAudioSystemReady]);
|
|
2042
2074
|
React10.useEffect(() => {
|
|
2043
2075
|
if (!sceneRef.current) return;
|
|
2044
2076
|
if (showAxes && !axesHelperRef.current) {
|
|
@@ -4438,7 +4470,9 @@ var StartScreen = ({
|
|
|
4438
4470
|
settingsText = "\u6E38\u620F\u8BBE\u7F6E",
|
|
4439
4471
|
aboutText = "\u5173\u4E8E\u4F5C\u54C1",
|
|
4440
4472
|
onStart,
|
|
4441
|
-
className = ""
|
|
4473
|
+
className = "",
|
|
4474
|
+
customSettingsContent,
|
|
4475
|
+
customAboutContent
|
|
4442
4476
|
}) => {
|
|
4443
4477
|
const [isMounted, setIsMounted] = React10.useState(false);
|
|
4444
4478
|
const [showSettings, setShowSettings] = React10.useState(false);
|
|
@@ -4543,7 +4577,7 @@ var StartScreen = ({
|
|
|
4543
4577
|
background: "rgba(248, 250, 252, 0.8)",
|
|
4544
4578
|
borderColor: "rgba(203, 213, 225, 0.3)"
|
|
4545
4579
|
} }, /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-[8px] sm:text-[10px] md:text-xs tracking-[0.3em] sm:tracking-[0.5em] font-light uppercase", style: { color: "rgba(100, 116, 139, 0.5)" } }, "Ver 1.6.2 \u2014 ENGINE POWERED BY SA2KIT"))),
|
|
4546
|
-
/* @__PURE__ */ React10__default.default.createElement(VNModal, { title: settingsText, show: showSettings, onClose: () => setShowSettings(false) }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-6 sm:space-y-8 py-2 sm:py-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex justify-between items-center text-xs sm:text-sm font-bold tracking-wider sm:tracking-widest", style: { color: "#64748b" } }, /* @__PURE__ */ React10__default.default.createElement("span", null, "MUSIC VOLUME"), /* @__PURE__ */ React10__default.default.createElement("span", null, "80%")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "h-2.5 sm:h-3 rounded-full p-0.5 border", style: { background: "rgba(241, 245, 249, 0.5)", borderColor: "rgba(203, 213, 225, 0.4)" } }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "h-full w-[80%] rounded-full", style: { background: "linear-gradient(to right, #22c55e, #4ade80)", boxShadow: "0 0 15px rgba(34, 197, 94, 0.5)" } }))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex justify-between items-center text-xs sm:text-sm font-bold tracking-wider sm:tracking-widest", style: { color: "#64748b" } }, /* @__PURE__ */ React10__default.default.createElement("span", null, "TEXT SPEED"), /* @__PURE__ */ React10__default.default.createElement("span", null, "NORMAL")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex gap-2 sm:gap-3" }, ["SLOW", "NORMAL", "FAST"].map((s, i) => /* @__PURE__ */ React10__default.default.createElement(
|
|
4580
|
+
/* @__PURE__ */ React10__default.default.createElement(VNModal, { title: settingsText, show: showSettings, onClose: () => setShowSettings(false) }, customSettingsContent ? /* @__PURE__ */ React10__default.default.createElement("div", { className: "py-2 sm:py-4" }, customSettingsContent) : /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-6 sm:space-y-8 py-2 sm:py-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex justify-between items-center text-xs sm:text-sm font-bold tracking-wider sm:tracking-widest", style: { color: "#64748b" } }, /* @__PURE__ */ React10__default.default.createElement("span", null, "MUSIC VOLUME"), /* @__PURE__ */ React10__default.default.createElement("span", null, "80%")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "h-2.5 sm:h-3 rounded-full p-0.5 border", style: { background: "rgba(241, 245, 249, 0.5)", borderColor: "rgba(203, 213, 225, 0.4)" } }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "h-full w-[80%] rounded-full", style: { background: "linear-gradient(to right, #22c55e, #4ade80)", boxShadow: "0 0 15px rgba(34, 197, 94, 0.5)" } }))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex justify-between items-center text-xs sm:text-sm font-bold tracking-wider sm:tracking-widest", style: { color: "#64748b" } }, /* @__PURE__ */ React10__default.default.createElement("span", null, "TEXT SPEED"), /* @__PURE__ */ React10__default.default.createElement("span", null, "NORMAL")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex gap-2 sm:gap-3" }, ["SLOW", "NORMAL", "FAST"].map((s, i) => /* @__PURE__ */ React10__default.default.createElement(
|
|
4547
4581
|
"div",
|
|
4548
4582
|
{
|
|
4549
4583
|
key: s,
|
|
@@ -4560,7 +4594,7 @@ var StartScreen = ({
|
|
|
4560
4594
|
},
|
|
4561
4595
|
s
|
|
4562
4596
|
)))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "pt-3 sm:pt-4 flex flex-col sm:flex-row items-center justify-between gap-2 sm:gap-0 opacity-50 italic text-[10px] sm:text-xs border-t", style: { borderColor: "rgba(203, 213, 225, 0.3)" } }, /* @__PURE__ */ React10__default.default.createElement("span", null, "Auto Save Enabled"), /* @__PURE__ */ React10__default.default.createElement("span", null, "Cloud Sync Active")))),
|
|
4563
|
-
/* @__PURE__ */ React10__default.default.createElement(VNModal, { title: aboutText, show: showAbout, onClose: () => setShowAbout(false) }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-6 sm:space-y-8 py-2 sm:py-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex items-center gap-3 sm:gap-6 p-4 sm:p-6 rounded-2xl sm:rounded-3xl border", style: { background: "rgba(241, 245, 249, 0.6)", borderColor: "rgba(203, 213, 225, 0.4)" } }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "w-14 h-14 sm:w-20 sm:h-20 rounded-xl sm:rounded-2xl flex items-center justify-center text-2xl sm:text-3xl font-black text-white shadow-lg shrink-0", style: { background: "linear-gradient(to bottom right, #22c55e, #4ade80)" } }, "S2"), /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("h3", { className: "text-lg sm:text-2xl font-black tracking-tight", style: { color: "#22c55e" } }, scriptName || "Project SA2"), /* @__PURE__ */ React10__default.default.createElement("p", { className: "text-[10px] sm:text-xs font-bold tracking-wider sm:tracking-widest mt-1 uppercase", style: { color: "rgba(100, 116, 139, 0.6)" } }, "Visual Novel Experience"))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4 px-1 sm:px-2" }, /* @__PURE__ */ React10__default.default.createElement("p", { className: "font-medium leading-relaxed text-sm sm:text-base", style: { color: "#475569" } }, "\u91C7\u7528 sa2kit \u5F15\u64CE\u6784\u5EFA\u7684\u65B0\u4E00\u4EE3\u5B9E\u65F6 3D \u89C6\u89C9\u5C0F\u8BF4\u3002\u7ED3\u5408\u4E86 MMD \u5B9E\u65F6\u6E32\u67D3\u6280\u672F\u4E0E\u4EA4\u4E92\u5F0F\u5267\u60C5\u5206\u652F\u7CFB\u7EDF\uFF0C\u81F4\u529B\u4E8E\u6253\u9020\u6781\u81F4\u7684\u6C89\u6D78\u5F0F\u53D9\u4E8B\u4F53\u9A8C\u3002")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "grid grid-cols-2 gap-3 sm:gap-4 pt-4 sm:pt-6 border-t", style: { borderColor: "rgba(203, 213, 225, 0.3)" } }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-[9px] sm:text-[10px] font-bold tracking-wider sm:tracking-widest", style: { color: "rgba(100, 116, 139, 0.5)" } }, "DEVELOPER"), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-xs font-bold", style: { color: "#64748b" } }, "SA2KIT TEAM")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex flex-col gap-1 text-right" }, /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-[9px] sm:text-[10px] font-bold tracking-wider sm:tracking-widest", style: { color: "rgba(100, 116, 139, 0.5)" } }, "ENGINE"), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-xs font-bold", style: { color: "#64748b" } }, "THREE.JS / REACT"))))),
|
|
4597
|
+
/* @__PURE__ */ React10__default.default.createElement(VNModal, { title: aboutText, show: showAbout, onClose: () => setShowAbout(false) }, customAboutContent ? /* @__PURE__ */ React10__default.default.createElement("div", { className: "py-2 sm:py-4" }, customAboutContent) : /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-6 sm:space-y-8 py-2 sm:py-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex items-center gap-3 sm:gap-6 p-4 sm:p-6 rounded-2xl sm:rounded-3xl border", style: { background: "rgba(241, 245, 249, 0.6)", borderColor: "rgba(203, 213, 225, 0.4)" } }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "w-14 h-14 sm:w-20 sm:h-20 rounded-xl sm:rounded-2xl flex items-center justify-center text-2xl sm:text-3xl font-black text-white shadow-lg shrink-0", style: { background: "linear-gradient(to bottom right, #22c55e, #4ade80)" } }, "S2"), /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("h3", { className: "text-lg sm:text-2xl font-black tracking-tight", style: { color: "#22c55e" } }, scriptName || "Project SA2"), /* @__PURE__ */ React10__default.default.createElement("p", { className: "text-[10px] sm:text-xs font-bold tracking-wider sm:tracking-widest mt-1 uppercase", style: { color: "rgba(100, 116, 139, 0.6)" } }, "Visual Novel Experience"))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4 px-1 sm:px-2" }, /* @__PURE__ */ React10__default.default.createElement("p", { className: "font-medium leading-relaxed text-sm sm:text-base", style: { color: "#475569" } }, "\u91C7\u7528 sa2kit \u5F15\u64CE\u6784\u5EFA\u7684\u65B0\u4E00\u4EE3\u5B9E\u65F6 3D \u89C6\u89C9\u5C0F\u8BF4\u3002\u7ED3\u5408\u4E86 MMD \u5B9E\u65F6\u6E32\u67D3\u6280\u672F\u4E0E\u4EA4\u4E92\u5F0F\u5267\u60C5\u5206\u652F\u7CFB\u7EDF\uFF0C\u81F4\u529B\u4E8E\u6253\u9020\u6781\u81F4\u7684\u6C89\u6D78\u5F0F\u53D9\u4E8B\u4F53\u9A8C\u3002")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "grid grid-cols-2 gap-3 sm:gap-4 pt-4 sm:pt-6 border-t", style: { borderColor: "rgba(203, 213, 225, 0.3)" } }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-[9px] sm:text-[10px] font-bold tracking-wider sm:tracking-widest", style: { color: "rgba(100, 116, 139, 0.5)" } }, "DEVELOPER"), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-xs font-bold", style: { color: "#64748b" } }, "SA2KIT TEAM")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex flex-col gap-1 text-right" }, /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-[9px] sm:text-[10px] font-bold tracking-wider sm:tracking-widest", style: { color: "rgba(100, 116, 139, 0.5)" } }, "ENGINE"), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-xs font-bold", style: { color: "#64748b" } }, "THREE.JS / REACT"))))),
|
|
4564
4598
|
/* @__PURE__ */ React10__default.default.createElement("style", null, `
|
|
4565
4599
|
@keyframes floatParticle {
|
|
4566
4600
|
from { transform: translateY(0) translateX(0); opacity: 0; }
|
|
@@ -4644,7 +4678,9 @@ var LoadingOverlay = ({
|
|
|
4644
4678
|
settingsText = "\u6E38\u620F\u8BBE\u7F6E",
|
|
4645
4679
|
aboutText = "\u5173\u4E8E\u4F5C\u54C1",
|
|
4646
4680
|
onStart,
|
|
4647
|
-
className = ""
|
|
4681
|
+
className = "",
|
|
4682
|
+
customSettingsContent,
|
|
4683
|
+
customAboutContent
|
|
4648
4684
|
}) => {
|
|
4649
4685
|
return /* @__PURE__ */ React10__default.default.createElement(React10__default.default.Fragment, null, /* @__PURE__ */ React10__default.default.createElement(
|
|
4650
4686
|
LoadingScreen,
|
|
@@ -4662,7 +4698,9 @@ var LoadingOverlay = ({
|
|
|
4662
4698
|
settingsText,
|
|
4663
4699
|
aboutText,
|
|
4664
4700
|
onStart,
|
|
4665
|
-
className
|
|
4701
|
+
className,
|
|
4702
|
+
customSettingsContent,
|
|
4703
|
+
customAboutContent
|
|
4666
4704
|
}
|
|
4667
4705
|
));
|
|
4668
4706
|
};
|
|
@@ -5069,6 +5107,8 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5069
5107
|
showHistoryButton = true,
|
|
5070
5108
|
showLightingDebugPanel = false,
|
|
5071
5109
|
lightingDebugInitialParams,
|
|
5110
|
+
customSettingsContent,
|
|
5111
|
+
customAboutContent,
|
|
5072
5112
|
className,
|
|
5073
5113
|
style
|
|
5074
5114
|
}, ref) => {
|
|
@@ -5467,7 +5507,9 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5467
5507
|
startText,
|
|
5468
5508
|
settingsText,
|
|
5469
5509
|
aboutText,
|
|
5470
|
-
onStart: handleStart
|
|
5510
|
+
onStart: handleStart,
|
|
5511
|
+
customSettingsContent,
|
|
5512
|
+
customAboutContent
|
|
5471
5513
|
}
|
|
5472
5514
|
),
|
|
5473
5515
|
(() => {
|
|
@@ -5588,6 +5630,224 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5588
5630
|
}
|
|
5589
5631
|
);
|
|
5590
5632
|
MMDVisualNovel.displayName = "MMDVisualNovel";
|
|
5633
|
+
var ModelSelectorSettings = ({
|
|
5634
|
+
characterModels,
|
|
5635
|
+
stageModels,
|
|
5636
|
+
selectedCharacterId,
|
|
5637
|
+
selectedStageId,
|
|
5638
|
+
onCharacterChange,
|
|
5639
|
+
onStageChange,
|
|
5640
|
+
characterLabel = "CHARACTER MODEL",
|
|
5641
|
+
stageLabel = "STAGE MODEL"
|
|
5642
|
+
}) => {
|
|
5643
|
+
return /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-6 sm:space-y-8" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex justify-between items-center text-xs sm:text-sm font-bold tracking-wider sm:tracking-widest", style: { color: "#64748b" } }, /* @__PURE__ */ React10__default.default.createElement("span", null, characterLabel), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-[10px] sm:text-xs opacity-60" }, characterModels.find((m) => m.id === selectedCharacterId)?.name || "\u672A\u9009\u62E9")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
5644
|
+
"select",
|
|
5645
|
+
{
|
|
5646
|
+
value: selectedCharacterId,
|
|
5647
|
+
onChange: (e) => onCharacterChange(e.target.value),
|
|
5648
|
+
className: "w-full h-12 sm:h-14 px-4 sm:px-6 rounded-xl sm:rounded-2xl border appearance-none cursor-pointer font-medium text-sm sm:text-base transition-all focus:outline-none focus:ring-2 focus:ring-green-500/30 touch-manipulation",
|
|
5649
|
+
style: {
|
|
5650
|
+
background: "linear-gradient(135deg, rgba(248, 250, 252, 0.98), rgba(226, 232, 240, 0.95))",
|
|
5651
|
+
borderColor: "rgba(203, 213, 225, 0.6)",
|
|
5652
|
+
color: "#475569",
|
|
5653
|
+
boxShadow: "0 2px 8px rgba(100, 116, 139, 0.1)"
|
|
5654
|
+
}
|
|
5655
|
+
},
|
|
5656
|
+
characterModels.map((model) => /* @__PURE__ */ React10__default.default.createElement("option", { key: model.id, value: model.id }, model.name))
|
|
5657
|
+
), /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute right-4 sm:right-6 top-1/2 -translate-y-1/2 pointer-events-none" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
5658
|
+
"svg",
|
|
5659
|
+
{
|
|
5660
|
+
className: "w-4 h-4 sm:w-5 sm:h-5",
|
|
5661
|
+
fill: "none",
|
|
5662
|
+
stroke: "currentColor",
|
|
5663
|
+
viewBox: "0 0 24 24",
|
|
5664
|
+
style: { color: "#64748b" }
|
|
5665
|
+
},
|
|
5666
|
+
/* @__PURE__ */ React10__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
|
|
5667
|
+
))), characterModels.find((m) => m.id === selectedCharacterId)?.thumbnail && /* @__PURE__ */ React10__default.default.createElement("div", { className: "mt-2 flex justify-center" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
5668
|
+
"img",
|
|
5669
|
+
{
|
|
5670
|
+
src: characterModels.find((m) => m.id === selectedCharacterId)?.thumbnail,
|
|
5671
|
+
alt: "Character preview",
|
|
5672
|
+
className: "h-20 sm:h-24 rounded-lg border object-cover",
|
|
5673
|
+
style: { borderColor: "rgba(203, 213, 225, 0.4)" }
|
|
5674
|
+
}
|
|
5675
|
+
))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-3 sm:space-y-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex justify-between items-center text-xs sm:text-sm font-bold tracking-wider sm:tracking-widest", style: { color: "#64748b" } }, /* @__PURE__ */ React10__default.default.createElement("span", null, stageLabel), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-[10px] sm:text-xs opacity-60" }, stageModels.find((m) => m.id === selectedStageId)?.name || "\u672A\u9009\u62E9")), /* @__PURE__ */ React10__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
5676
|
+
"select",
|
|
5677
|
+
{
|
|
5678
|
+
value: selectedStageId,
|
|
5679
|
+
onChange: (e) => onStageChange(e.target.value),
|
|
5680
|
+
className: "w-full h-12 sm:h-14 px-4 sm:px-6 rounded-xl sm:rounded-2xl border appearance-none cursor-pointer font-medium text-sm sm:text-base transition-all focus:outline-none focus:ring-2 focus:ring-green-500/30 touch-manipulation",
|
|
5681
|
+
style: {
|
|
5682
|
+
background: "linear-gradient(135deg, rgba(248, 250, 252, 0.98), rgba(226, 232, 240, 0.95))",
|
|
5683
|
+
borderColor: "rgba(203, 213, 225, 0.6)",
|
|
5684
|
+
color: "#475569",
|
|
5685
|
+
boxShadow: "0 2px 8px rgba(100, 116, 139, 0.1)"
|
|
5686
|
+
}
|
|
5687
|
+
},
|
|
5688
|
+
stageModels.map((model) => /* @__PURE__ */ React10__default.default.createElement("option", { key: model.id, value: model.id }, model.name))
|
|
5689
|
+
), /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute right-4 sm:right-6 top-1/2 -translate-y-1/2 pointer-events-none" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
5690
|
+
"svg",
|
|
5691
|
+
{
|
|
5692
|
+
className: "w-4 h-4 sm:w-5 sm:h-5",
|
|
5693
|
+
fill: "none",
|
|
5694
|
+
stroke: "currentColor",
|
|
5695
|
+
viewBox: "0 0 24 24",
|
|
5696
|
+
style: { color: "#64748b" }
|
|
5697
|
+
},
|
|
5698
|
+
/* @__PURE__ */ React10__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
|
|
5699
|
+
))), stageModels.find((m) => m.id === selectedStageId)?.thumbnail && /* @__PURE__ */ React10__default.default.createElement("div", { className: "mt-2 flex justify-center" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
5700
|
+
"img",
|
|
5701
|
+
{
|
|
5702
|
+
src: stageModels.find((m) => m.id === selectedStageId)?.thumbnail,
|
|
5703
|
+
alt: "Stage preview",
|
|
5704
|
+
className: "h-20 sm:h-24 rounded-lg border object-cover",
|
|
5705
|
+
style: { borderColor: "rgba(203, 213, 225, 0.4)" }
|
|
5706
|
+
}
|
|
5707
|
+
))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "pt-3 sm:pt-4 flex items-center justify-center gap-2 opacity-50 italic text-[10px] sm:text-xs border-t", style: { borderColor: "rgba(203, 213, 225, 0.3)" } }, /* @__PURE__ */ React10__default.default.createElement("svg", { className: "w-3.5 h-3.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React10__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" })), /* @__PURE__ */ React10__default.default.createElement("span", null, "\u9009\u62E9\u7684\u6A21\u578B\u5C06\u5E94\u7528\u5230\u6240\u6709\u573A\u666F")));
|
|
5708
|
+
};
|
|
5709
|
+
ModelSelectorSettings.displayName = "ModelSelectorSettings";
|
|
5710
|
+
|
|
5711
|
+
// src/mmd/visual-novel/MMDVisualNovelWithSelector.tsx
|
|
5712
|
+
var MMDVisualNovelWithSelector = React10.forwardRef((props, ref) => {
|
|
5713
|
+
const {
|
|
5714
|
+
script,
|
|
5715
|
+
modelSelector,
|
|
5716
|
+
onModelSelectionChange,
|
|
5717
|
+
...restProps
|
|
5718
|
+
} = props;
|
|
5719
|
+
const {
|
|
5720
|
+
characterModels,
|
|
5721
|
+
stageModels,
|
|
5722
|
+
defaultCharacterId,
|
|
5723
|
+
defaultStageId,
|
|
5724
|
+
characterLabel,
|
|
5725
|
+
stageLabel
|
|
5726
|
+
} = modelSelector;
|
|
5727
|
+
const visualNovelRef = React10.useRef(null);
|
|
5728
|
+
const [selectedCharacterId, setSelectedCharacterId] = React10.useState(
|
|
5729
|
+
defaultCharacterId || characterModels[0]?.id || ""
|
|
5730
|
+
);
|
|
5731
|
+
const [selectedStageId, setSelectedStageId] = React10.useState(
|
|
5732
|
+
defaultStageId || stageModels[0]?.id || ""
|
|
5733
|
+
);
|
|
5734
|
+
const selectedCharacterPath = React10.useMemo(() => {
|
|
5735
|
+
const model = characterModels.find((m) => m.id === selectedCharacterId);
|
|
5736
|
+
return model?.path || characterModels[0]?.path || "";
|
|
5737
|
+
}, [characterModels, selectedCharacterId]);
|
|
5738
|
+
const selectedStagePath = React10.useMemo(() => {
|
|
5739
|
+
const model = stageModels.find((m) => m.id === selectedStageId);
|
|
5740
|
+
return model?.path || stageModels[0]?.path || "";
|
|
5741
|
+
}, [stageModels, selectedStageId]);
|
|
5742
|
+
const modifiedScript = React10.useMemo(() => {
|
|
5743
|
+
return {
|
|
5744
|
+
...script,
|
|
5745
|
+
nodes: script.nodes.map((node) => ({
|
|
5746
|
+
...node,
|
|
5747
|
+
resources: {
|
|
5748
|
+
...node.resources,
|
|
5749
|
+
// 覆盖人物模型路径
|
|
5750
|
+
modelPath: selectedCharacterPath,
|
|
5751
|
+
// 覆盖场景模型路径
|
|
5752
|
+
stageModelPath: selectedStagePath
|
|
5753
|
+
}
|
|
5754
|
+
}))
|
|
5755
|
+
};
|
|
5756
|
+
}, [script, selectedCharacterPath, selectedStagePath]);
|
|
5757
|
+
const handleCharacterChange = React10.useCallback((id) => {
|
|
5758
|
+
setSelectedCharacterId(id);
|
|
5759
|
+
onModelSelectionChange?.(id, selectedStageId);
|
|
5760
|
+
}, [selectedStageId, onModelSelectionChange]);
|
|
5761
|
+
const handleStageChange = React10.useCallback((id) => {
|
|
5762
|
+
setSelectedStageId(id);
|
|
5763
|
+
onModelSelectionChange?.(selectedCharacterId, id);
|
|
5764
|
+
}, [selectedCharacterId, onModelSelectionChange]);
|
|
5765
|
+
const customSettingsContent = React10.useMemo(() => /* @__PURE__ */ React10__default.default.createElement(
|
|
5766
|
+
ModelSelectorSettings,
|
|
5767
|
+
{
|
|
5768
|
+
characterModels,
|
|
5769
|
+
stageModels,
|
|
5770
|
+
selectedCharacterId,
|
|
5771
|
+
selectedStageId,
|
|
5772
|
+
onCharacterChange: handleCharacterChange,
|
|
5773
|
+
onStageChange: handleStageChange,
|
|
5774
|
+
characterLabel,
|
|
5775
|
+
stageLabel
|
|
5776
|
+
}
|
|
5777
|
+
), [
|
|
5778
|
+
characterModels,
|
|
5779
|
+
stageModels,
|
|
5780
|
+
selectedCharacterId,
|
|
5781
|
+
selectedStageId,
|
|
5782
|
+
handleCharacterChange,
|
|
5783
|
+
handleStageChange,
|
|
5784
|
+
characterLabel,
|
|
5785
|
+
stageLabel
|
|
5786
|
+
]);
|
|
5787
|
+
React10.useImperativeHandle(ref, () => ({
|
|
5788
|
+
// 继承 MMDVisualNovelRef 的所有方法
|
|
5789
|
+
goToNode: (nodeIndex, force) => {
|
|
5790
|
+
visualNovelRef.current?.goToNode(nodeIndex, force);
|
|
5791
|
+
},
|
|
5792
|
+
goToDialogue: (dialogueIndex) => {
|
|
5793
|
+
visualNovelRef.current?.goToDialogue(dialogueIndex);
|
|
5794
|
+
},
|
|
5795
|
+
getCurrentNodeIndex: () => {
|
|
5796
|
+
return visualNovelRef.current?.getCurrentNodeIndex() ?? 0;
|
|
5797
|
+
},
|
|
5798
|
+
getCurrentDialogueIndex: () => {
|
|
5799
|
+
return visualNovelRef.current?.getCurrentDialogueIndex() ?? 0;
|
|
5800
|
+
},
|
|
5801
|
+
getHistory: () => {
|
|
5802
|
+
return visualNovelRef.current?.getHistory() ?? [];
|
|
5803
|
+
},
|
|
5804
|
+
getVariables: () => {
|
|
5805
|
+
return visualNovelRef.current?.getVariables() ?? {};
|
|
5806
|
+
},
|
|
5807
|
+
setVariable: (key, value) => {
|
|
5808
|
+
visualNovelRef.current?.setVariable(key, value);
|
|
5809
|
+
},
|
|
5810
|
+
setAutoMode: (enabled) => {
|
|
5811
|
+
visualNovelRef.current?.setAutoMode(enabled);
|
|
5812
|
+
},
|
|
5813
|
+
skipTyping: () => {
|
|
5814
|
+
visualNovelRef.current?.skipTyping();
|
|
5815
|
+
},
|
|
5816
|
+
triggerEffect: (effect) => {
|
|
5817
|
+
visualNovelRef.current?.triggerEffect?.(effect);
|
|
5818
|
+
},
|
|
5819
|
+
// 新增的模型选择方法
|
|
5820
|
+
getSelectedCharacterId: () => selectedCharacterId,
|
|
5821
|
+
getSelectedStageId: () => selectedStageId,
|
|
5822
|
+
setCharacterModel: (id) => {
|
|
5823
|
+
if (characterModels.some((m) => m.id === id)) {
|
|
5824
|
+
handleCharacterChange(id);
|
|
5825
|
+
}
|
|
5826
|
+
},
|
|
5827
|
+
setStageModel: (id) => {
|
|
5828
|
+
if (stageModels.some((m) => m.id === id)) {
|
|
5829
|
+
handleStageChange(id);
|
|
5830
|
+
}
|
|
5831
|
+
}
|
|
5832
|
+
}), [
|
|
5833
|
+
selectedCharacterId,
|
|
5834
|
+
selectedStageId,
|
|
5835
|
+
characterModels,
|
|
5836
|
+
stageModels,
|
|
5837
|
+
handleCharacterChange,
|
|
5838
|
+
handleStageChange
|
|
5839
|
+
]);
|
|
5840
|
+
return /* @__PURE__ */ React10__default.default.createElement(
|
|
5841
|
+
MMDVisualNovel,
|
|
5842
|
+
{
|
|
5843
|
+
ref: visualNovelRef,
|
|
5844
|
+
script: modifiedScript,
|
|
5845
|
+
customSettingsContent,
|
|
5846
|
+
...restProps
|
|
5847
|
+
}
|
|
5848
|
+
);
|
|
5849
|
+
});
|
|
5850
|
+
MMDVisualNovelWithSelector.displayName = "MMDVisualNovelWithSelector";
|
|
5591
5851
|
var MusicControls = ({
|
|
5592
5852
|
isPlaying,
|
|
5593
5853
|
currentTime,
|
|
@@ -5799,7 +6059,7 @@ var MMDMusicPlayer = React10.forwardRef(
|
|
|
5799
6059
|
const [isUIVisible, setIsUIVisible] = React10.useState(true);
|
|
5800
6060
|
const [isCameraManual, setIsCameraManual] = React10.useState(false);
|
|
5801
6061
|
const [searchKeyword, setSearchKeyword] = React10.useState("");
|
|
5802
|
-
const { search, searchResult, isSearching, getSongUrl } =
|
|
6062
|
+
const { search, searchResult, isSearching, getSongUrl } = chunkE7RGBAYJ_js.useMusic();
|
|
5803
6063
|
React10.useEffect(() => {
|
|
5804
6064
|
if (mikuMode && tracks.length === 0) {
|
|
5805
6065
|
search({ keyword: "", miku: true });
|
|
@@ -6076,41 +6336,129 @@ var MMDMusicPlayer = React10.forwardRef(
|
|
|
6076
6336
|
}
|
|
6077
6337
|
);
|
|
6078
6338
|
MMDMusicPlayer.displayName = "MMDMusicPlayer";
|
|
6339
|
+
function Select({
|
|
6340
|
+
label,
|
|
6341
|
+
options,
|
|
6342
|
+
value,
|
|
6343
|
+
onChange,
|
|
6344
|
+
placeholder = "\u8BF7\u9009\u62E9...",
|
|
6345
|
+
allowEmpty = false,
|
|
6346
|
+
emptyLabel = "\u65E0"
|
|
6347
|
+
}) {
|
|
6348
|
+
const selectedOption = options.find((opt) => opt.id === value);
|
|
6349
|
+
const showPlaceholder = !selectedOption && !allowEmpty && value !== "";
|
|
6350
|
+
return /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-xs font-medium text-white/50 ml-1 uppercase tracking-wider" }, label), /* @__PURE__ */ React10__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
6351
|
+
"select",
|
|
6352
|
+
{
|
|
6353
|
+
value,
|
|
6354
|
+
onChange: (e) => onChange(e.target.value),
|
|
6355
|
+
className: "w-full appearance-none bg-white/5 border border-white/10 rounded-xl px-4 py-3 pr-10 text-sm text-white focus:outline-none focus:border-cyan-500/50 transition-colors cursor-pointer hover:bg-white/10"
|
|
6356
|
+
},
|
|
6357
|
+
showPlaceholder && /* @__PURE__ */ React10__default.default.createElement("option", { value: "", disabled: true, className: "bg-gray-900 text-white/50" }, placeholder),
|
|
6358
|
+
allowEmpty && /* @__PURE__ */ React10__default.default.createElement("option", { value: "", className: "bg-gray-900 text-white/60" }, emptyLabel),
|
|
6359
|
+
options.map((option) => /* @__PURE__ */ React10__default.default.createElement(
|
|
6360
|
+
"option",
|
|
6361
|
+
{
|
|
6362
|
+
key: option.id,
|
|
6363
|
+
value: option.id,
|
|
6364
|
+
className: "bg-gray-900 text-white"
|
|
6365
|
+
},
|
|
6366
|
+
option.name
|
|
6367
|
+
))
|
|
6368
|
+
), /* @__PURE__ */ React10__default.default.createElement(lucideReact.ChevronDown, { className: "absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-white/40 pointer-events-none" })));
|
|
6369
|
+
}
|
|
6079
6370
|
var MMDARPlayer = React10.forwardRef((props, ref) => {
|
|
6080
6371
|
const {
|
|
6081
|
-
resources,
|
|
6082
6372
|
stage = {},
|
|
6083
6373
|
mobileOptimization,
|
|
6084
6374
|
cameraConfig = { facingMode: "user" },
|
|
6085
6375
|
mirrored,
|
|
6086
6376
|
showSettings = true,
|
|
6377
|
+
modelPresets,
|
|
6378
|
+
motionPresets,
|
|
6379
|
+
audioPresets = [],
|
|
6380
|
+
defaultModelId,
|
|
6381
|
+
defaultMotionId,
|
|
6382
|
+
defaultAudioId,
|
|
6383
|
+
initialModelVisible = false,
|
|
6384
|
+
placementText = "TOUCH!",
|
|
6087
6385
|
autoPlay = true,
|
|
6088
6386
|
loop = true,
|
|
6089
6387
|
onCameraReady,
|
|
6090
6388
|
onCameraError,
|
|
6091
6389
|
onResourcesChange,
|
|
6390
|
+
onModelPlaced,
|
|
6092
6391
|
onLoad,
|
|
6093
6392
|
onError,
|
|
6094
6393
|
className,
|
|
6095
6394
|
style
|
|
6096
6395
|
} = props;
|
|
6396
|
+
const initialModelId = defaultModelId || modelPresets[0]?.id || "";
|
|
6397
|
+
const initialMotionId = defaultMotionId || motionPresets[0]?.id || "";
|
|
6398
|
+
const initialAudioId = defaultAudioId || audioPresets[0]?.id || "";
|
|
6097
6399
|
const videoRef = React10.useRef(null);
|
|
6098
6400
|
const playerRef = React10.useRef(null);
|
|
6099
6401
|
const streamRef = React10.useRef(null);
|
|
6402
|
+
const containerRef = React10.useRef(null);
|
|
6100
6403
|
const [isCameraStarted, setIsCameraStarted] = React10.useState(false);
|
|
6101
6404
|
const [cameraError, setCameraError] = React10.useState(null);
|
|
6102
6405
|
const [facingMode, setFacingMode] = React10.useState(cameraConfig.facingMode || "user");
|
|
6103
|
-
const [isLoading, setIsLoading] = React10.useState(
|
|
6406
|
+
const [isLoading, setIsLoading] = React10.useState(false);
|
|
6104
6407
|
const [isSettingsOpen, setIsSettingsOpen] = React10.useState(false);
|
|
6105
|
-
const [
|
|
6106
|
-
const [
|
|
6107
|
-
React10.
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6408
|
+
const [selectedModelId, setSelectedModelId] = React10.useState(initialModelId);
|
|
6409
|
+
const [selectedMotionId, setSelectedMotionId] = React10.useState(initialMotionId);
|
|
6410
|
+
const [selectedAudioId, setSelectedAudioId] = React10.useState(initialAudioId);
|
|
6411
|
+
const [isModelPlaced, setIsModelPlaced] = React10.useState(initialModelVisible);
|
|
6412
|
+
const [placementAnimation, setPlacementAnimation] = React10.useState(false);
|
|
6413
|
+
const currentResources = React10.useMemo(() => {
|
|
6414
|
+
const model = modelPresets.find((m) => m.id === selectedModelId);
|
|
6415
|
+
const motion = motionPresets.find((m) => m.id === selectedMotionId);
|
|
6416
|
+
const audio = audioPresets.find((a) => a.id === selectedAudioId);
|
|
6417
|
+
return {
|
|
6418
|
+
modelPath: model?.modelPath || modelPresets[0]?.modelPath || "",
|
|
6419
|
+
motionPath: motion?.motionPath || motionPresets[0]?.motionPath || "",
|
|
6420
|
+
audioPath: audio?.audioPath
|
|
6421
|
+
};
|
|
6422
|
+
}, [selectedModelId, selectedMotionId, selectedAudioId, modelPresets, motionPresets, audioPresets]);
|
|
6113
6423
|
const shouldMirror = mirrored !== void 0 ? mirrored : facingMode === "user";
|
|
6424
|
+
const placeModel = React10.useCallback(() => {
|
|
6425
|
+
if (isModelPlaced) return;
|
|
6426
|
+
setPlacementAnimation(true);
|
|
6427
|
+
setIsLoading(true);
|
|
6428
|
+
setTimeout(() => {
|
|
6429
|
+
setIsModelPlaced(true);
|
|
6430
|
+
setPlacementAnimation(false);
|
|
6431
|
+
onModelPlaced?.();
|
|
6432
|
+
}, 300);
|
|
6433
|
+
}, [isModelPlaced, onModelPlaced]);
|
|
6434
|
+
const removeModel = React10.useCallback(() => {
|
|
6435
|
+
setIsModelPlaced(false);
|
|
6436
|
+
setIsLoading(false);
|
|
6437
|
+
}, []);
|
|
6438
|
+
const switchModel = React10.useCallback((newResources) => {
|
|
6439
|
+
const matchedModel = modelPresets.find((m) => m.modelPath === newResources.modelPath);
|
|
6440
|
+
const matchedMotion = motionPresets.find((m) => m.motionPath === newResources.motionPath);
|
|
6441
|
+
const matchedAudio = audioPresets.find((a) => a.audioPath === newResources.audioPath);
|
|
6442
|
+
if (matchedModel) setSelectedModelId(matchedModel.id);
|
|
6443
|
+
if (matchedMotion) setSelectedMotionId(matchedMotion.id);
|
|
6444
|
+
if (matchedAudio) setSelectedAudioId(matchedAudio.id);
|
|
6445
|
+
onResourcesChange?.(newResources);
|
|
6446
|
+
if (isModelPlaced) {
|
|
6447
|
+
setIsLoading(true);
|
|
6448
|
+
}
|
|
6449
|
+
}, [isModelPlaced, onResourcesChange, modelPresets, motionPresets, audioPresets]);
|
|
6450
|
+
const applySettings = React10.useCallback(() => {
|
|
6451
|
+
onResourcesChange?.(currentResources);
|
|
6452
|
+
setIsSettingsOpen(false);
|
|
6453
|
+
if (isModelPlaced) {
|
|
6454
|
+
setIsLoading(true);
|
|
6455
|
+
}
|
|
6456
|
+
}, [currentResources, isModelPlaced, onResourcesChange]);
|
|
6457
|
+
const resetPosition = React10.useCallback(() => {
|
|
6458
|
+
setIsModelPlaced(false);
|
|
6459
|
+
setIsLoading(false);
|
|
6460
|
+
setIsSettingsOpen(false);
|
|
6461
|
+
}, []);
|
|
6114
6462
|
const startCamera = React10.useCallback(async (mode = facingMode) => {
|
|
6115
6463
|
try {
|
|
6116
6464
|
setCameraError(null);
|
|
@@ -6171,22 +6519,27 @@ var MMDARPlayer = React10.forwardRef((props, ref) => {
|
|
|
6171
6519
|
if (shouldMirror) {
|
|
6172
6520
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
6173
6521
|
}
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6522
|
+
if (isModelPlaced) {
|
|
6523
|
+
const mmdBase64 = playerRef.current.snapshot();
|
|
6524
|
+
const mmdImg = new Image();
|
|
6525
|
+
mmdImg.src = mmdBase64;
|
|
6526
|
+
await new Promise((resolve) => {
|
|
6527
|
+
mmdImg.onload = () => {
|
|
6528
|
+
ctx.drawImage(mmdImg, 0, 0, canvas.width, canvas.height);
|
|
6529
|
+
resolve(null);
|
|
6530
|
+
};
|
|
6531
|
+
});
|
|
6532
|
+
}
|
|
6183
6533
|
return canvas.toDataURL("image/png");
|
|
6184
|
-
}, [shouldMirror]);
|
|
6534
|
+
}, [shouldMirror, isModelPlaced]);
|
|
6185
6535
|
React10.useImperativeHandle(ref, () => ({
|
|
6186
6536
|
startCamera,
|
|
6187
6537
|
stopCamera,
|
|
6188
6538
|
switchCamera,
|
|
6189
|
-
snapshot
|
|
6539
|
+
snapshot,
|
|
6540
|
+
placeModel,
|
|
6541
|
+
removeModel,
|
|
6542
|
+
switchModel
|
|
6190
6543
|
}));
|
|
6191
6544
|
React10.useEffect(() => {
|
|
6192
6545
|
if (autoPlay) {
|
|
@@ -6194,9 +6547,13 @@ var MMDARPlayer = React10.forwardRef((props, ref) => {
|
|
|
6194
6547
|
}
|
|
6195
6548
|
return () => stopCamera();
|
|
6196
6549
|
}, [autoPlay, startCamera, stopCamera]);
|
|
6550
|
+
React10.useEffect(() => {
|
|
6551
|
+
onResourcesChange?.(currentResources);
|
|
6552
|
+
}, [currentResources, onResourcesChange]);
|
|
6197
6553
|
return /* @__PURE__ */ React10__default.default.createElement(
|
|
6198
6554
|
"div",
|
|
6199
6555
|
{
|
|
6556
|
+
ref: containerRef,
|
|
6200
6557
|
className: `relative w-full h-full bg-black overflow-hidden ${className}`,
|
|
6201
6558
|
style
|
|
6202
6559
|
},
|
|
@@ -6211,26 +6568,25 @@ var MMDARPlayer = React10.forwardRef((props, ref) => {
|
|
|
6211
6568
|
style: { zIndex: 0 }
|
|
6212
6569
|
}
|
|
6213
6570
|
),
|
|
6214
|
-
/* @__PURE__ */ React10__default.default.createElement(
|
|
6571
|
+
isModelPlaced && /* @__PURE__ */ React10__default.default.createElement(
|
|
6215
6572
|
"div",
|
|
6216
6573
|
{
|
|
6217
|
-
className:
|
|
6574
|
+
className: `absolute inset-0 w-full h-full transition-all duration-500 ${placementAnimation ? "scale-110 opacity-0" : "scale-100 opacity-100"}`,
|
|
6218
6575
|
style: { zIndex: 1 }
|
|
6219
6576
|
},
|
|
6220
6577
|
/* @__PURE__ */ React10__default.default.createElement(
|
|
6221
6578
|
MMDPlayerBase,
|
|
6222
6579
|
{
|
|
6580
|
+
key: `${selectedModelId}-${selectedMotionId}-${selectedAudioId}`,
|
|
6223
6581
|
ref: playerRef,
|
|
6224
6582
|
resources: currentResources,
|
|
6225
6583
|
stage: {
|
|
6226
6584
|
...stage,
|
|
6227
6585
|
backgroundColor: "transparent",
|
|
6228
|
-
// 强制透明背景
|
|
6229
6586
|
cameraPosition: stage.cameraPosition || { x: 0, y: 15, z: 40 }
|
|
6230
|
-
// 针对 AR 场景稍调高相机
|
|
6231
6587
|
},
|
|
6232
6588
|
mobileOptimization,
|
|
6233
|
-
autoPlay,
|
|
6589
|
+
autoPlay: true,
|
|
6234
6590
|
loop,
|
|
6235
6591
|
onLoad: () => {
|
|
6236
6592
|
setIsLoading(false);
|
|
@@ -6240,6 +6596,30 @@ var MMDARPlayer = React10.forwardRef((props, ref) => {
|
|
|
6240
6596
|
}
|
|
6241
6597
|
)
|
|
6242
6598
|
),
|
|
6599
|
+
!isModelPlaced && isCameraStarted && /* @__PURE__ */ React10__default.default.createElement(
|
|
6600
|
+
"div",
|
|
6601
|
+
{
|
|
6602
|
+
className: "absolute inset-0 z-5 flex items-center justify-center",
|
|
6603
|
+
onClick: placeModel
|
|
6604
|
+
},
|
|
6605
|
+
/* @__PURE__ */ React10__default.default.createElement(
|
|
6606
|
+
"button",
|
|
6607
|
+
{
|
|
6608
|
+
onClick: placeModel,
|
|
6609
|
+
className: `
|
|
6610
|
+
relative group cursor-pointer
|
|
6611
|
+
transition-all duration-300 ease-out
|
|
6612
|
+
hover:scale-110 active:scale-95
|
|
6613
|
+
${placementAnimation ? "scale-150 opacity-0" : "scale-100 opacity-100"}
|
|
6614
|
+
`
|
|
6615
|
+
},
|
|
6616
|
+
/* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 -m-4 rounded-2xl bg-cyan-400/20 animate-ping" }),
|
|
6617
|
+
/* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 -m-2 rounded-xl bg-cyan-400/30 animate-pulse" }),
|
|
6618
|
+
/* @__PURE__ */ React10__default.default.createElement("div", { className: "relative bg-gradient-to-br from-cyan-400 via-blue-500 to-purple-600 p-1 rounded-2xl shadow-2xl shadow-cyan-500/50" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "bg-black/80 backdrop-blur-xl px-8 py-6 rounded-xl flex flex-col items-center gap-3" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.Sparkles, { className: "w-10 h-10 text-cyan-400 animate-pulse" }), /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 w-10 h-10 bg-cyan-400/30 blur-xl" })), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-2xl font-black text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 to-purple-400 tracking-widest" }, placementText), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-xs text-white/50 font-medium" }, "\u70B9\u51FB\u53EC\u5524 Miku \u2728"))),
|
|
6619
|
+
/* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute -top-2 -right-2 w-4 h-4 bg-yellow-400 rounded-full animate-bounce shadow-lg shadow-yellow-400/50" }),
|
|
6620
|
+
/* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute -bottom-1 -left-1 w-3 h-3 bg-pink-400 rounded-full animate-bounce delay-100 shadow-lg shadow-pink-400/50" })
|
|
6621
|
+
)
|
|
6622
|
+
),
|
|
6243
6623
|
/* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 z-10 pointer-events-none flex flex-col justify-between p-6" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex justify-between items-start pointer-events-auto" }, cameraError ? /* @__PURE__ */ React10__default.default.createElement("div", { className: "bg-red-500/80 backdrop-blur-md text-white px-4 py-2 rounded-full flex items-center gap-2 text-sm" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.AlertCircle, { className: "w-4 h-4" }), cameraError, /* @__PURE__ */ React10__default.default.createElement(
|
|
6244
6624
|
"button",
|
|
6245
6625
|
{
|
|
@@ -6247,12 +6627,12 @@ var MMDARPlayer = React10.forwardRef((props, ref) => {
|
|
|
6247
6627
|
className: "ml-2 underline"
|
|
6248
6628
|
},
|
|
6249
6629
|
"\u91CD\u8BD5"
|
|
6250
|
-
)) : /* @__PURE__ */ React10__default.default.createElement("div", { className: "bg-black/40 backdrop-blur-md text-white px-4 py-2 rounded-full flex items-center gap-2 text-sm" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.Camera, { className: "w-4 h-4 text-green-400" }), isCameraStarted ? "\u5B9E\u666F AR \u6A21\u5F0F\
|
|
6630
|
+
)) : /* @__PURE__ */ React10__default.default.createElement("div", { className: "bg-black/40 backdrop-blur-md text-white px-4 py-2 rounded-full flex items-center gap-2 text-sm" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.Camera, { className: "w-4 h-4 text-green-400" }), isCameraStarted ? isModelPlaced ? "\u5B9E\u666F AR \u6A21\u5F0F" : "\u70B9\u51FB\u653E\u7F6E\u6A21\u578B" : "\u7B49\u5F85\u6444\u50CF\u5934..."), /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex flex-col gap-2" }, showSettings && /* @__PURE__ */ React10__default.default.createElement(
|
|
6251
6631
|
"button",
|
|
6252
6632
|
{
|
|
6253
6633
|
onClick: () => setIsSettingsOpen(!isSettingsOpen),
|
|
6254
|
-
className: `p-3 backdrop-blur-md rounded-full text-white transition-all active:scale-95 pointer-events-auto ${isSettingsOpen ? "bg-
|
|
6255
|
-
title: "\u8BBE\u7F6E
|
|
6634
|
+
className: `p-3 backdrop-blur-md rounded-full text-white transition-all active:scale-95 pointer-events-auto ${isSettingsOpen ? "bg-cyan-500" : "bg-white/10 hover:bg-white/20"}`,
|
|
6635
|
+
title: "\u8BBE\u7F6E"
|
|
6256
6636
|
},
|
|
6257
6637
|
/* @__PURE__ */ React10__default.default.createElement(lucideReact.Settings, { className: "w-5 h-5" })
|
|
6258
6638
|
), /* @__PURE__ */ React10__default.default.createElement(
|
|
@@ -6271,45 +6651,59 @@ var MMDARPlayer = React10.forwardRef((props, ref) => {
|
|
|
6271
6651
|
title: isCameraStarted ? "\u5173\u95ED\u6444\u50CF\u5934" : "\u5F00\u542F\u6444\u50CF\u5934"
|
|
6272
6652
|
},
|
|
6273
6653
|
isCameraStarted ? /* @__PURE__ */ React10__default.default.createElement(lucideReact.CameraOff, { className: "w-5 h-5" }) : /* @__PURE__ */ React10__default.default.createElement(lucideReact.Camera, { className: "w-5 h-5" })
|
|
6274
|
-
))), isSettingsOpen && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute top-20 right-6 w-
|
|
6654
|
+
))), isSettingsOpen && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute top-20 right-6 w-72 bg-black/90 backdrop-blur-xl border border-white/10 rounded-2xl p-5 pointer-events-auto shadow-2xl animate-in slide-in-from-right-4 duration-300" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex items-center justify-between mb-5" }, /* @__PURE__ */ React10__default.default.createElement("h3", { className: "text-white font-bold flex items-center gap-2" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.Settings, { className: "w-4 h-4 text-cyan-400" }), "AR \u8BBE\u7F6E"), /* @__PURE__ */ React10__default.default.createElement(
|
|
6275
6655
|
"button",
|
|
6276
6656
|
{
|
|
6277
6657
|
onClick: () => setIsSettingsOpen(false),
|
|
6278
|
-
className: "p-1 hover:bg-white/10 rounded-full transition-colors text-white/60"
|
|
6658
|
+
className: "p-1.5 hover:bg-white/10 rounded-full transition-colors text-white/60"
|
|
6279
6659
|
},
|
|
6280
6660
|
/* @__PURE__ */ React10__default.default.createElement(lucideReact.X, { className: "w-4 h-4" })
|
|
6281
|
-
)), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
6282
|
-
|
|
6661
|
+
)), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
6662
|
+
Select,
|
|
6283
6663
|
{
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6664
|
+
label: "\u9009\u62E9\u6A21\u578B",
|
|
6665
|
+
options: modelPresets,
|
|
6666
|
+
value: selectedModelId,
|
|
6667
|
+
onChange: setSelectedModelId,
|
|
6668
|
+
placeholder: "\u8BF7\u9009\u62E9\u6A21\u578B..."
|
|
6289
6669
|
}
|
|
6290
|
-
)
|
|
6291
|
-
|
|
6670
|
+
), /* @__PURE__ */ React10__default.default.createElement(
|
|
6671
|
+
Select,
|
|
6292
6672
|
{
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
}
|
|
6299
|
-
)
|
|
6673
|
+
label: "\u9009\u62E9\u52A8\u4F5C",
|
|
6674
|
+
options: motionPresets,
|
|
6675
|
+
value: selectedMotionId,
|
|
6676
|
+
onChange: setSelectedMotionId,
|
|
6677
|
+
placeholder: "\u8BF7\u9009\u62E9\u52A8\u4F5C..."
|
|
6678
|
+
}
|
|
6679
|
+
), audioPresets.length > 0 && /* @__PURE__ */ React10__default.default.createElement(
|
|
6680
|
+
Select,
|
|
6681
|
+
{
|
|
6682
|
+
label: "\u9009\u62E9\u97F3\u4E50",
|
|
6683
|
+
options: audioPresets,
|
|
6684
|
+
value: selectedAudioId,
|
|
6685
|
+
onChange: setSelectedAudioId,
|
|
6686
|
+
placeholder: "\u8BF7\u9009\u62E9\u97F3\u4E50...",
|
|
6687
|
+
allowEmpty: true,
|
|
6688
|
+
emptyLabel: "\u{1F507} \u4E0D\u64AD\u653E\u97F3\u4E50"
|
|
6689
|
+
}
|
|
6690
|
+
), /* @__PURE__ */ React10__default.default.createElement("div", { className: "pt-3 space-y-2" }, isModelPlaced && /* @__PURE__ */ React10__default.default.createElement(
|
|
6300
6691
|
"button",
|
|
6301
6692
|
{
|
|
6302
|
-
onClick:
|
|
6303
|
-
|
|
6304
|
-
onResourcesChange?.(tempResources);
|
|
6305
|
-
setIsSettingsOpen(false);
|
|
6306
|
-
setIsLoading(true);
|
|
6307
|
-
},
|
|
6308
|
-
className: "w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-3 rounded-xl flex items-center justify-center gap-2 transition-all active:scale-95 shadow-lg shadow-blue-500/20"
|
|
6693
|
+
onClick: applySettings,
|
|
6694
|
+
className: "w-full bg-cyan-500 hover:bg-cyan-600 text-white font-bold py-3 rounded-xl flex items-center justify-center gap-2 transition-all active:scale-95 shadow-lg shadow-cyan-500/20"
|
|
6309
6695
|
},
|
|
6310
|
-
/* @__PURE__ */ React10__default.default.createElement(lucideReact.
|
|
6696
|
+
/* @__PURE__ */ React10__default.default.createElement(lucideReact.Sparkles, { className: "w-4 h-4" }),
|
|
6311
6697
|
"\u5E94\u7528\u66F4\u6539"
|
|
6312
|
-
)
|
|
6698
|
+
), /* @__PURE__ */ React10__default.default.createElement(
|
|
6699
|
+
"button",
|
|
6700
|
+
{
|
|
6701
|
+
onClick: resetPosition,
|
|
6702
|
+
className: `w-full ${isModelPlaced ? "bg-white/5 hover:bg-white/10 text-white/70" : "bg-cyan-500 hover:bg-cyan-600 text-white shadow-lg shadow-cyan-500/20"} font-medium py-3 rounded-xl flex items-center justify-center gap-2 transition-all active:scale-95 border border-white/10`
|
|
6703
|
+
},
|
|
6704
|
+
/* @__PURE__ */ React10__default.default.createElement(lucideReact.RotateCcw, { className: "w-4 h-4" }),
|
|
6705
|
+
isModelPlaced ? "\u91CD\u7F6E\u4F4D\u7F6E" : "\u5F00\u59CB\u653E\u7F6E"
|
|
6706
|
+
)))), isLoading && isModelPlaced && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex flex-col items-center gap-3" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "w-12 h-12 border-4 border-cyan-500/30 border-t-cyan-500 rounded-full animate-spin" }), /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-white text-sm font-medium bg-black/40 px-3 py-1 rounded-full backdrop-blur-sm" }, "\u6B63\u5728\u53EC\u5524 Miku..."))))
|
|
6313
6707
|
);
|
|
6314
6708
|
});
|
|
6315
6709
|
MMDARPlayer.displayName = "MMDARPlayer";
|
|
@@ -8428,6 +8822,8 @@ exports.MMDPlayerEnhancedDebugInfo = MMDPlayerEnhancedDebugInfo;
|
|
|
8428
8822
|
exports.MMDPlaylist = MMDPlaylist;
|
|
8429
8823
|
exports.MMDPlaylistDebugInfo = MMDPlaylistDebugInfo;
|
|
8430
8824
|
exports.MMDVisualNovel = MMDVisualNovel;
|
|
8825
|
+
exports.MMDVisualNovelWithSelector = MMDVisualNovelWithSelector;
|
|
8826
|
+
exports.ModelSelectorSettings = ModelSelectorSettings;
|
|
8431
8827
|
exports.MultiFXAdapter = MultiFXAdapter;
|
|
8432
8828
|
exports.MusicControls = MusicControls;
|
|
8433
8829
|
exports.PMXEditor = PMXEditor2;
|