Skip to content

Commit 0bb806e

Browse files
committed
feat: stop performance drain when hiding live2d
1 parent 50c1f55 commit 0bb806e

File tree

2 files changed

+55
-15
lines changed

2 files changed

+55
-15
lines changed

app/Live2DApp.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class Live2DApp {
2525
private static _showHitAreaFrames = false
2626
private static _showModelFrame = false
2727
private static _showStats = false
28+
private static _cachedModel: Live2DModel | null = null
2829

2930
static async init(options: Live2dOptions, live2dTipsHandler: Live2dTipsHandler) {
3031
settings.RENDER_OPTIONS.hello = !options.skipHello
@@ -183,6 +184,32 @@ export class Live2DApp {
183184
}, 100)
184185
}
185186

187+
static hideModel() {
188+
if (this.model?.live2dModel) {
189+
this._cachedModel = this.model.live2dModel
190+
this.pixiApp.stage.removeChild(this.model.live2dModel)
191+
}
192+
}
193+
194+
static async showModel() {
195+
if (this._cachedModel && !this.pixiApp.stage.children.includes(this._cachedModel)) {
196+
this.pixiApp.stage.addChild(this._cachedModel)
197+
}
198+
}
199+
200+
static async destroyModel() {
201+
this.clearAppStage()
202+
203+
if (this.model) {
204+
this.model.destroy()
205+
this.model = null
206+
}
207+
}
208+
209+
static async restoreModel(source: string | ModelSettings) {
210+
await this.loadModel(source);
211+
}
212+
186213
@save('stats')
187214
static set showStats(value: boolean) {
188215
this._showStats = value

client/composable.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Live2DApp as Live2DAppType } from '../app/Live2DApp'
2-
import { isClient, useWindowSize } from '@vueuse/core'
3-
import { ref, watch } from 'vue'
2+
import { isClient, useWindowSize, useTimeoutFn, createSharedComposable } from '@vueuse/core'
3+
import { ref, watch, onUnmounted } from 'vue'
44
import { Live2dTipsHandler } from '../helpers/tips'
55
import { hideLive2dTool, showLive2dTool } from '../utils/animate'
66
import { getCookie, setCookie } from '../utils/cookie'
@@ -9,20 +9,15 @@ import { convertJsdelivrUrlToGithubApiUrl, getFilenamesFromGitHub } from '../uti
99
import { getLive2DModel, setLive2DModelKeys } from '../utils/storage'
1010
import { useAddonLive2dConfig } from './options'
1111

12-
let isInitialized = false
13-
const live2DApp = ref<typeof Live2DAppType>()
14-
const isLive2DHide = ref(false)
15-
16-
export function useAddonLive2d() {
12+
export const useAddonLive2d = createSharedComposable(() => {
1713
const live2dOptions = useAddonLive2dConfig()
1814
const { randomCharacter, randomSkin, live2DCollection, live2dTips, hideOnScreenSizes, defaultVisibility, cookieExpires } = live2dOptions.value
1915
const { width } = useWindowSize()
20-
16+
const live2DApp = ref<typeof Live2DAppType>()
17+
const isLive2DHide = ref(false)
2118
const live2dTipsHandler = new Live2dTipsHandler(live2dTips!)
22-
19+
2320
async function _initializeLive2DApp() {
24-
isInitialized = true
25-
2621
await import('../lib/index.js')
2722
live2DApp.value = (await import('../app/Live2DApp')).Live2DApp
2823

@@ -141,28 +136,39 @@ export function useAddonLive2d() {
141136
live2DApp.value?.captureFrame()
142137
}
143138

139+
const { start: startHideModel, stop: stopHideModel } = useTimeoutFn(
140+
() => live2DApp.value?.hideModel(),
141+
2000,
142+
{ immediate: false }
143+
)
144+
144145
function hideLive2D() {
145146
isLive2DHide.value = true
146-
147147
hideLive2dTool()
148148

149149
const live2dElement = document.getElementById('live2d')!
150150
// localStorage.setItem('live2d-display', Date.now().toString())
151151
live2dTipsHandler.showMessage(live2dTips!.tool.display, 2000, 11)
152152
live2dElement.style.bottom = '-100%'
153153

154+
stopHideModel()
155+
startHideModel()
156+
154157
setTimeout(() => {
155158
setCookie('live2d', 'Hide', cookieExpires)
156159
}, 0)
157160
}
158161

159162
function showLive2D() {
160163
isLive2DHide.value = false
161-
162164
showLive2dTool()
163165

164166
const live2dElement = document.getElementById('live2d')!
165167
live2dElement.style.bottom = '0px'
168+
169+
stopHideModel()
170+
live2DApp.value?.showModel()
171+
166172
setTimeout(() => {
167173
// localStorage.removeItem('live2d-display')
168174
live2dElement.style.display = ''
@@ -172,7 +178,14 @@ export function useAddonLive2d() {
172178

173179
const toggleLive2DVisibility = () => isLive2DHide.value ? showLive2D() : hideLive2D()
174180

175-
if (isClient && !isInitialized)
181+
onUnmounted(() => {
182+
if (live2DApp.value) {
183+
live2DApp.value.destroyModel()
184+
live2DApp.value = undefined
185+
}
186+
})
187+
188+
if (isClient)
176189
_initializeLive2DApp()
177190

178191
return {
@@ -190,4 +203,4 @@ export function useAddonLive2d() {
190203
isLive2DHide,
191204
live2dTipsHandler,
192205
}
193-
}
206+
})

0 commit comments

Comments
 (0)