From 7d541a486ecf9380c69a8f46e68d73c58e7e6506 Mon Sep 17 00:00:00 2001 From: ayangweb <75017711+ayangweb@users.noreply.github.com> Date: Fri, 11 Jul 2025 19:29:49 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=B0=BA=E5=AF=B8=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20(#552)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/composables/useModel.ts | 34 ++++++++++++++++------------------ src/pages/main/index.vue | 27 ++++++++++++++++++++------- src/utils/dom.ts | 15 --------------- src/utils/live2d.ts | 2 ++ 4 files changed, 38 insertions(+), 40 deletions(-) delete mode 100644 src/utils/dom.ts diff --git a/src/composables/useModel.ts b/src/composables/useModel.ts index 0ad4f1f..7391190 100644 --- a/src/composables/useModel.ts +++ b/src/composables/useModel.ts @@ -1,37 +1,34 @@ -import { convertFileSrc } from '@tauri-apps/api/core' import { LogicalSize, PhysicalSize } from '@tauri-apps/api/dpi' import { resolveResource } from '@tauri-apps/api/path' import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow' import { message } from 'ant-design-vue' import { isNil, round } from 'es-toolkit' -import { computed, watch } from 'vue' +import { ref, watch } from 'vue' import live2d from '../utils/live2d' import { getCursorMonitor } from '../utils/monitor' import { useCatStore } from '@/stores/cat' import { useModelStore } from '@/stores/model' -import { getImageSize } from '@/utils/dom' -import { join } from '@/utils/path' const appWindow = getCurrentWebviewWindow() +interface ModelSize { + width: number + height: number +} + export function useModel() { const modelStore = useModelStore() const catStore = useCatStore() - - const backgroundImage = computed(() => { - if (!modelStore.currentModel) return - - return convertFileSrc(join(modelStore.currentModel.path, 'resources', 'background.png')) - }) + const modelSize = ref() watch(() => modelStore.currentModel, handleLoad, { deep: true, immediate: true }) - watch([() => catStore.scale, backgroundImage], async () => { - if (!backgroundImage.value) return + watch([() => catStore.scale, modelSize], async () => { + if (!modelSize.value) return - const { width, height } = await getImageSize(backgroundImage.value) + const { width, height } = modelSize.value appWindow.setSize( new PhysicalSize({ @@ -49,11 +46,13 @@ export function useModel() { await resolveResource(path) - const data = await live2d.load(path) + const { width, height, ...rest } = await live2d.load(path) + + modelSize.value = { width, height } handleResize() - Object.assign(modelStore, data) + Object.assign(modelStore, rest) } catch (error) { message.error(String(error)) } @@ -64,11 +63,11 @@ export function useModel() { } async function handleResize() { - if (!backgroundImage.value) return + if (!modelSize.value) return live2d.fitModel() - const { width, height } = await getImageSize(backgroundImage.value) + const { width, height } = modelSize.value if (round(innerWidth / innerHeight, 1) !== round(width / height, 1)) { await appWindow.setSize( @@ -134,7 +133,6 @@ export function useModel() { } return { - backgroundImage, handleLoad, handleDestroy, handleResize, diff --git a/src/pages/main/index.vue b/src/pages/main/index.vue index 3c2ad00..956014e 100644 --- a/src/pages/main/index.vue +++ b/src/pages/main/index.vue @@ -2,6 +2,7 @@ import { convertFileSrc, invoke } from '@tauri-apps/api/core' import { Menu } from '@tauri-apps/api/menu' import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow' +import { exists } from '@tauri-apps/plugin-fs' import { useDebounceFn, useEventListener } from '@vueuse/core' import { onMounted, onUnmounted, ref, watch } from 'vue' @@ -16,11 +17,12 @@ import { join } from '@/utils/path' const appWindow = getCurrentWebviewWindow() const { pressedMouses, mousePosition, pressedLeftKeys, pressedRightKeys } = useDevice() -const { backgroundImage, handleDestroy, handleResize, handleMouseDown, handleMouseMove, handleKeyDown } = useModel() +const { handleDestroy, handleResize, handleMouseDown, handleMouseMove, handleKeyDown } = useModel() const catStore = useCatStore() const { getSharedMenu } = useSharedMenu() const modelStore = useModelStore() const resizing = ref(false) +const backgroundImagePath = ref() onMounted(() => { invoke(INVOKE_KEY.START_DEVICE_LISTENING) @@ -62,6 +64,16 @@ watch(() => catStore.penetrable, (value) => { watch(() => catStore.alwaysOnTop, setAlwaysOnTop, { immediate: true }) +watch(() => modelStore.currentModel, async (model) => { + if (!model) return + + const path = join(model.path, 'resources', 'background.png') + + const existed = await exists(path) + + backgroundImagePath.value = existed ? convertFileSrc(path) : void 0 +}, { deep: true, immediate: true }) + function handleWindowDrag() { appWindow.startDragging() } @@ -76,7 +88,7 @@ async function handleContextmenu(event: MouseEvent) { menu.popup() } -function resolveImagePath(key: string, side: 'left' | 'right' = 'left') { +function resolveKeyImagePath(key: string, side: 'left' | 'right' = 'left') { return convertFileSrc(join(modelStore.currentModel!.path, 'resources', `${side}-keys`, `${key}.png`)) } @@ -89,22 +101,23 @@ function resolveImagePath(key: string, side: 'left' | 'right' = 'left') { @contextmenu="handleContextmenu" @mousedown="handleWindowDrag" > - +
((resolve, reject) => { - const img = new Image() - - img.src = src - - img.onload = () => { - const { naturalWidth, naturalHeight } = img - - resolve({ width: naturalWidth, height: naturalHeight }) - } - - img.onerror = reject - }) -} diff --git a/src/utils/live2d.ts b/src/utils/live2d.ts index ff4f9e8..8d4530a 100644 --- a/src/utils/live2d.ts +++ b/src/utils/live2d.ts @@ -67,6 +67,8 @@ class Live2d { const { motions, expressions } = modelSettings return { + width, + height, motions, expressions, }