feat(stage-tamagotchi): follow cursor

This commit is contained in:
Neko Ayaka
2025-10-13 09:27:46 +08:00
parent 69c4df9702
commit 3203381981
9 changed files with 67 additions and 14 deletions
@@ -2,19 +2,16 @@ export function useLoop(fn: () => Promise<void> | void, options?: { interval?: n
let timer: NodeJS.Timeout | null = null
let shouldRun = options?.autoStart ?? true
const loopIteration = () => {
const loopIteration = async () => {
if (!shouldRun) {
return
}
const res = fn()
if (res instanceof Promise) {
res.finally(() => {
timer = setTimeout(loopIteration, options?.interval ?? 1000 / 60) // Default to ~60 FPS
})
try {
await fn()
}
else {
timer = setTimeout(loopIteration, options?.interval ?? 1000 / 60)
finally {
timer = setTimeout(loopIteration, options?.interval ?? 1000 / 60) // Default to ~60 FPS
}
}
@@ -5,9 +5,11 @@ import { createContext } from '@unbird/eventa/adapters/electron/main'
import { ipcMain } from 'electron'
import { electronOpenSettingsDevtools } from '../../../../shared/eventa'
import { createFadeOnHoverService } from '../../../services/fade-on-hover'
export async function setupSettingsWindowInvokes(params: { settingsWindow: BrowserWindow }) {
const { context } = createContext(ipcMain, params.settingsWindow)
createFadeOnHoverService(context)
defineInvokeHandler(context, electronOpenSettingsDevtools, async () => params.settingsWindow.webContents.openDevTools({ mode: 'detach' }))
}
@@ -136,7 +136,7 @@ const Key = defineComponent({
<slot />
</template>
<!-- <route lang="yaml">
<route lang="yaml">
meta:
layout: settings
</route> -->
</route>
@@ -0,0 +1,20 @@
<script setup lang="ts">
import { useWindowMouse } from '../../stores/window-mouse'
const { x, y } = useWindowMouse()
</script>
<template>
<div class="flex flex-col md:flex-row">
<div>
<div class="flex justify-center gap-3">
{{ x }}, {{ y }}
</div>
</div>
</div>
</template>
<route lang="yaml">
meta:
layout: settings
</route>
@@ -18,6 +18,12 @@ const menu = computed(() => [
icon: 'i-solar:sledgehammer-bold-duotone',
to: '/devtools/use-magic-keys',
},
{
title: t('tamagotchi.settings.pages.system.developer.sections.section.use-window-mouse.title'),
description: t('tamagotchi.settings.pages.system.developer.sections.section.use-window-mouse.description'),
icon: 'i-solar:sledgehammer-bold-duotone',
to: '/devtools/use-window-mouse',
},
])
const { context } = createContext(window.electron.ipcRenderer)
@@ -0,0 +1,24 @@
import { defineInvoke } from '@unbird/eventa'
import { createContext } from '@unbird/eventa/adapters/electron/renderer'
import { ref } from 'vue'
import { electronCursorPoint, electronStartTrackingCursorPoint } from '../../shared/eventa'
export function useWindowMouse(options?: { x: number, y: number }) {
const context = ref(createContext(window.electron.ipcRenderer).context)
const centerPosition = ref<{ x: number, y: number }>({ x: 0, y: 0 })
const positionX = ref(options?.x ?? 0)
const positionY = ref(options?.y ?? 0)
context.value!.on(electronCursorPoint, (event) => {
positionX.value = event.body?.x ?? centerPosition.value.x
positionY.value = event.body?.y ?? centerPosition.value.y
})
defineInvoke(context.value!, electronStartTrackingCursorPoint)()
return {
x: positionX,
y: positionY,
}
}
@@ -2,17 +2,15 @@ import { useWindowSize } from '@vueuse/core'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
// import { useTauriWindowClickThrough } from '../composables/tauri-window-pass-through-on-hover'
import { useWindowControlStore } from './window-controls'
import { useWindowMouse } from './window-mouse'
export const useWindowStore = defineStore('tamagotchi-window', () => {
const windowControlStore = useWindowControlStore()
const { width, height } = useWindowSize()
const centerPos = computed(() => ({ x: width.value / 2, y: height.value / 2 }))
// const { live2dLookAtX, live2dLookAtY, isCursorInside } = useTauriWindowClickThrough(centerPos)
const live2dLookAtX = ref(0)
const live2dLookAtY = ref(0)
const { x: live2dLookAtX, y: live2dLookAtY } = useWindowMouse(centerPos.value)
const isCursorInside = ref(false)
const shouldHideView = computed(() => isCursorInside.value && !windowControlStore.isControlActive && windowControlStore.isIgnoringMouseEvent)
@@ -21,3 +21,9 @@ pages:
toggle-ignore-mouse-event:
label: Toggle Ignore Mouse Event
press-keys: Press Keys...
developer:
sections:
section:
use-window-mouse:
title: useWindowMouse
description: Test the Electron window cursor position