mirror of
https://github.com/ayangweb/BongoCat.git
synced 2026-03-12 17:51:48 +08:00
refactor: dynamic calculation of background image size (#375)
This commit is contained in:
@@ -1,16 +1,18 @@
|
||||
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 { round } from 'es-toolkit'
|
||||
import { watch } from 'vue'
|
||||
import { computed, watch } from 'vue'
|
||||
|
||||
import live2d from '../utils/live2d'
|
||||
import { getCursorMonitor } from '../utils/monitor'
|
||||
|
||||
import { DEFAULT_MODEL_HEIGHT, DEFAULT_MODEL_WIDTH } from '@/constants'
|
||||
import { useCatStore } from '@/stores/cat'
|
||||
import { useModelStore } from '@/stores/model'
|
||||
import { getImageSize } from '@/utils/dom'
|
||||
import { join } from '@/utils/path'
|
||||
|
||||
const appWindow = getCurrentWebviewWindow()
|
||||
|
||||
@@ -18,22 +20,26 @@ export function useModel() {
|
||||
const modelStore = useModelStore()
|
||||
const catStore = useCatStore()
|
||||
|
||||
const backgroundImage = computed(() => {
|
||||
return convertFileSrc(join(modelStore.currentModel!.path, 'resources', 'background.png'))
|
||||
})
|
||||
|
||||
watch(() => modelStore.currentModel, handleLoad, { deep: true, immediate: true })
|
||||
|
||||
watch(() => catStore.scale, async () => {
|
||||
const { width, height } = await getImageSize(backgroundImage.value)
|
||||
|
||||
appWindow.setSize(
|
||||
new PhysicalSize({
|
||||
width: round(DEFAULT_MODEL_WIDTH * (catStore.scale / 100)),
|
||||
height: round(DEFAULT_MODEL_HEIGHT * (catStore.scale / 100)),
|
||||
width: round(width * (catStore.scale / 100)),
|
||||
height: round(height * (catStore.scale / 100)),
|
||||
}),
|
||||
)
|
||||
}, { immediate: true })
|
||||
|
||||
async function handleLoad() {
|
||||
try {
|
||||
if (!modelStore.currentModel) return
|
||||
|
||||
const { path } = modelStore.currentModel
|
||||
const { path } = modelStore.currentModel!
|
||||
|
||||
await resolveResource(path)
|
||||
|
||||
@@ -56,20 +62,22 @@ export function useModel() {
|
||||
|
||||
const { innerWidth, innerHeight } = window
|
||||
|
||||
live2d.model?.scale.set(innerWidth / DEFAULT_MODEL_WIDTH)
|
||||
const { width, height } = await getImageSize(backgroundImage.value)
|
||||
|
||||
if (round(innerWidth / innerHeight, 1) !== round(DEFAULT_MODEL_WIDTH / DEFAULT_MODEL_HEIGHT, 1)) {
|
||||
live2d.model?.scale.set(innerWidth / width)
|
||||
|
||||
if (round(innerWidth / innerHeight, 1) !== round(width / height, 1)) {
|
||||
await appWindow.setSize(
|
||||
new LogicalSize({
|
||||
width: innerWidth,
|
||||
height: Math.ceil(innerWidth * (DEFAULT_MODEL_HEIGHT / DEFAULT_MODEL_WIDTH)),
|
||||
height: Math.ceil(innerWidth * (height / width)),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const size = await appWindow.size()
|
||||
|
||||
catStore.scale = round((size.width / DEFAULT_MODEL_WIDTH) * 100)
|
||||
catStore.scale = round((size.width / width) * 100)
|
||||
}
|
||||
|
||||
function handleKeyDown(side: 'left' | 'right', pressed: boolean) {
|
||||
@@ -109,6 +117,7 @@ export function useModel() {
|
||||
}
|
||||
|
||||
return {
|
||||
backgroundImage,
|
||||
handleLoad,
|
||||
handleDestroy,
|
||||
handleResize,
|
||||
|
||||
@@ -7,10 +7,6 @@ export const LISTEN_KEY = {
|
||||
UPDATE_APP: 'update-app',
|
||||
}
|
||||
|
||||
export const DEFAULT_MODEL_WIDTH = 612
|
||||
|
||||
export const DEFAULT_MODEL_HEIGHT = 354
|
||||
|
||||
export const INVOKE_KEY = {
|
||||
COPY_DIR: 'copy_dir',
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { Menu } from '@tauri-apps/api/menu'
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
import { useDebounceFn, useEventListener } from '@vueuse/core'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import { useDevice } from '@/composables/useDevice'
|
||||
import { useModel } from '@/composables/useModel'
|
||||
@@ -14,7 +14,7 @@ import { join } from '@/utils/path'
|
||||
|
||||
const appWindow = getCurrentWebviewWindow()
|
||||
const { pressedMouses, mousePosition, pressedLeftKeys, pressedRightKeys } = useDevice()
|
||||
const { handleDestroy, handleResize, handleMouseDown, handleMouseMove, handleKeyDown } = useModel()
|
||||
const { backgroundImage, handleDestroy, handleResize, handleMouseDown, handleMouseMove, handleKeyDown } = useModel()
|
||||
const catStore = useCatStore()
|
||||
const { getSharedMenu } = useSharedMenu()
|
||||
const modelStore = useModelStore()
|
||||
@@ -51,12 +51,6 @@ watch(() => catStore.penetrable, (value) => {
|
||||
appWindow.setIgnoreCursorEvents(value)
|
||||
}, { immediate: true })
|
||||
|
||||
const backgroundImage = computed(() => {
|
||||
if (!modelStore.currentModel) return
|
||||
|
||||
return convertFileSrc(join(modelStore.currentModel.path, 'resources', 'background.png'))
|
||||
})
|
||||
|
||||
function handleWindowDrag() {
|
||||
appWindow.startDragging()
|
||||
}
|
||||
@@ -72,9 +66,7 @@ async function handleContextmenu(event: MouseEvent) {
|
||||
}
|
||||
|
||||
function resolveImagePath(key: string, side: 'left' | 'right' = 'left') {
|
||||
if (!modelStore.currentModel) return
|
||||
|
||||
return convertFileSrc(join(modelStore.currentModel.path, 'resources', `${side}-keys`, `${key}.png`))
|
||||
return convertFileSrc(join(modelStore.currentModel!.path, 'resources', `${side}-keys`, `${key}.png`))
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
15
src/utils/dom.ts
Normal file
15
src/utils/dom.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export function getImageSize(src: string) {
|
||||
return new Promise<{ width: number, height: number }>((resolve, reject) => {
|
||||
const img = new Image()
|
||||
|
||||
img.src = src
|
||||
|
||||
img.onload = () => {
|
||||
const { naturalWidth, naturalHeight } = img
|
||||
|
||||
resolve({ width: naturalWidth, height: naturalHeight })
|
||||
}
|
||||
|
||||
img.onerror = reject
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user