fix(spineplayer): fixed disposal

This commit is contained in:
Haoyu Xu
2024-10-10 23:53:21 +08:00
parent befa29e948
commit a0cb679b4d
2 changed files with 26 additions and 33 deletions

View File

@@ -33,7 +33,7 @@ const getVoiceFoler = (lang) => {
const voiceFolder = folderObject.sub.find(e => e.lang === lang) || folderObject.sub.find(e => e.name === 'custom') const voiceFolder = folderObject.sub.find(e => e.lang === lang) || folderObject.sub.find(e => e.name === 'custom')
return `${folderObject.main}/${voiceFolder.name}` return `${folderObject.main}/${voiceFolder.name}`
} }
const defaultSpineAnimation = 'Idle' const defaultSpineAnimationName = 'Idle'
const backgroundAtom = atom(BACKGROUNDS[0]) const backgroundAtom = atom(BACKGROUNDS[0])
const getPartialName = (type, input) => { const getPartialName = (type, input) => {
@@ -76,10 +76,9 @@ export default function Operator() {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const _trackEvt = useUmami(`/${key}`, `${key}`) const _trackEvt = useUmami(`/${key}`, `${key}`)
const spineRef = useRef(null) const spineRef = useRef(null)
const [spineAnimation, setSpineAnimation] = useState(defaultSpineAnimation) const [spineAnimationName, setSpineAnimationName] = useState(defaultSpineAnimationName)
const { i18n } = useI18n() const { i18n } = useI18n()
const [spinePlayer, setSpinePlayer] = useState(null) const [spinePlayer, setSpinePlayer] = useState(null)
const [prevLink, setPrevLink] = useState(null)
const [voiceLang, _setVoiceLang] = useState(null) const [voiceLang, _setVoiceLang] = useState(null)
const [currentBackground, setCurrentBackground] = useAtom(backgroundAtom) const [currentBackground, setCurrentBackground] = useAtom(backgroundAtom)
const [voiceConfig, setVoiceConfig] = useState(null) const [voiceConfig, setVoiceConfig] = useState(null)
@@ -121,7 +120,7 @@ export default function Operator() {
setConfig(config) setConfig(config)
configRef.current = config configRef.current = config
fetch(`/${import.meta.env.VITE_DIRECTORY_FOLDER}/${config.filename.replace("#", "%23")}.json`).then(res => res.json()).then(data => { fetch(`/${import.meta.env.VITE_DIRECTORY_FOLDER}/${config.filename.replace("#", "%23")}.json`).then(res => res.json()).then(data => {
setSpineAnimation(defaultSpineAnimation) setSpineAnimationName(defaultSpineAnimationName)
setSpineData(data) setSpineData(data)
}) })
setHeaderIcon(config.type) setHeaderIcon(config.type)
@@ -178,7 +177,7 @@ export default function Operator() {
skelUrl: `./assets/${config.filename.replace('#', '%23')}.skel`, skelUrl: `./assets/${config.filename.replace('#', '%23')}.skel`,
atlasUrl: `./assets/${config.filename.replace('#', '%23')}.atlas`, atlasUrl: `./assets/${config.filename.replace('#', '%23')}.atlas`,
rawDataURIs: spineData, rawDataURIs: spineData,
animation: spineAnimation, animation: spineAnimationName,
premultipliedAlpha: true, premultipliedAlpha: true,
alpha: true, alpha: true,
backgroundColor: "#00000000", backgroundColor: "#00000000",
@@ -223,15 +222,17 @@ export default function Operator() {
} else { } else {
playerConfig.skelUrl = `./assets/${config.filename.replace('#', '%23')}.skel`; playerConfig.skelUrl = `./assets/${config.filename.replace('#', '%23')}.skel`;
} }
setPrevLink(config.link)
setSpinePlayer(new spine.SpinePlayer(spineRef.current, playerConfig)) setSpinePlayer(new spine.SpinePlayer(spineRef.current, playerConfig))
} }
}, [config, spineData, spineAnimationName, setSpinePlayer, spinePlayer]);
useEffect(() => {
return () => { return () => {
if (spinePlayer && prevLink === config.link) { if (spinePlayer) {
spinePlayer.dispose() spinePlayer.dispose()
} }
} }
}, [config, spineData, spineAnimation, setSpinePlayer, spinePlayer, prevLink]); }, [spinePlayer])
useEffect(() => { useEffect(() => {
if (voiceConfig && voiceLang) { if (voiceConfig && voiceLang) {
@@ -302,42 +303,34 @@ export default function Operator() {
} }
}, [voiceLang]) }, [voiceLang])
const setSpineAnimation = useCallback((animation) => {
playAnimationVoice(animation)
const entry = spinePlayer.animationState.setAnimation(0, animation, true)
entry.mixDuration = 0.3;
setSpineAnimationName(animation)
}, [playAnimationVoice, spinePlayer])
const spineSettings = [ const spineSettings = [
{ {
name: 'animation', name: 'animation',
options: [ options: [
{ {
name: 'idle', name: 'idle',
onClick: () => { onClick: () => setSpineAnimation("Idle"),
const animation = "Idle"
playAnimationVoice(animation)
spinePlayer.animationState.setAnimation(0, animation, true, 0)
setSpineAnimation(animation)
},
activeRule: () => { activeRule: () => {
return spineAnimation === 'Idle' return spineAnimationName === 'Idle'
} }
}, { }, {
name: 'interact', name: 'interact',
onClick: () => { onClick: () => setSpineAnimation("Interact"),
const animation = "Interact"
playAnimationVoice(animation)
spinePlayer.animationState.setAnimation(0, animation, true, 0)
setSpineAnimation(animation)
},
activeRule: () => { activeRule: () => {
return spineAnimation === 'Interact' return spineAnimationName === 'Interact'
} }
}, { }, {
name: 'special', name: 'special',
onClick: () => { onClick: () => setSpineAnimation("Special"),
const animation = "Special"
playAnimationVoice(animation)
spinePlayer.animationState.setAnimation(0, animation, true, 0)
setSpineAnimation(animation)
},
activeRule: () => { activeRule: () => {
return spineAnimation === 'Special' return spineAnimationName === 'Special'
} }
} }
] ]
@@ -353,7 +346,7 @@ export default function Operator() {
setVoiceLang(null) setVoiceLang(null)
} }
if (!isVoicePlayingRef.current) { if (!isVoicePlayingRef.current) {
playAnimationVoice(spineAnimation) playAnimationVoice(spineAnimationName)
} }
}, },
activeRule: () => { activeRule: () => {

View File

@@ -30,7 +30,7 @@ export default function spinePlayer(el) {
defaultMix: 0, defaultMix: 0,
success: function (widget) { success: function (widget) {
if (widget.skeleton.data.animations.map(e => e.name).includes("Start") && window.settings.useStartAnimation) { if (widget.skeleton.data.animations.map(e => e.name).includes("Start") && window.settings.useStartAnimation) {
widget.animationState.setAnimation(0, "Start", false, 0) widget.animationState.setAnimation(0, "Start", false)
} }
widget.animationState.addAnimation(0, "Idle", true, 0); widget.animationState.addAnimation(0, "Idle", true, 0);
widget.animationState.addListener({ widget.animationState.addListener({
@@ -42,7 +42,7 @@ export default function spinePlayer(el) {
complete: () => { complete: () => {
if (window.performance.now() - resetTime >= 8 * 1000 && Math.random() < 0.3) { if (window.performance.now() - resetTime >= 8 * 1000 && Math.random() < 0.3) {
resetTime = window.performance.now(); resetTime = window.performance.now();
let entry = widget.animationState.setAnimation(0, "Special", false, 0); let entry = widget.animationState.setAnimation(0, "Special", false);
entry.mixDuration = 0.3; entry.mixDuration = 0.3;
widget.animationState.addAnimation(0, "Idle", true, 0); widget.animationState.addAnimation(0, "Idle", true, 0);
} }
@@ -53,7 +53,7 @@ export default function spinePlayer(el) {
return; return;
} }
isPlayingInteract = true; isPlayingInteract = true;
let entry = widget.animationState.setAnimation(0, "Interact", false, 0); let entry = widget.animationState.setAnimation(0, "Interact", false);
entry.mixDuration = 0.3; entry.mixDuration = 0.3;
widget.animationState.addAnimation(0, "Idle", true, 0); widget.animationState.addAnimation(0, "Idle", true, 0);
} }