feat(stage-tamagotchi): even better fade on hover
This commit is contained in:
@@ -3,5 +3,6 @@ export { useElectronEventaContext, useElectronEventaInvoke } from './use-electro
|
||||
export { useElectronMouse, useElectronMouseEventTarget } from './use-electron-mouse'
|
||||
export type { UseMouseInElementReturn } from './use-electron-mouse-in-element'
|
||||
export { useElectronMouseInElement } from './use-electron-mouse-in-element'
|
||||
export { useElectronMouseInWindow } from './use-electron-mouse-in-window'
|
||||
export { useElectronRelativeMouse } from './use-electron-relative-mouse'
|
||||
export { useElectronWindowBounds } from './use-electron-window-bounds'
|
||||
|
||||
+1
-25
@@ -1,34 +1,10 @@
|
||||
import type { MaybeElementRef, UseMouseOptions } from '@vueuse/core'
|
||||
import type { MaybeElementRef, MouseInElementOptions } from '@vueuse/core'
|
||||
|
||||
import { defaultWindow, tryOnMounted, unrefElement, useEventListener, useMutationObserver, useResizeObserver } from '@vueuse/core'
|
||||
import { shallowRef, watch } from 'vue'
|
||||
|
||||
import { useElectronRelativeMouse } from '../use-electron-relative-mouse'
|
||||
|
||||
export interface MouseInElementOptions extends UseMouseOptions {
|
||||
/**
|
||||
* Whether to handle mouse events when the cursor is outside the target element.
|
||||
* When enabled, mouse position will continue to be tracked even when outside the element bounds.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
handleOutside?: boolean
|
||||
|
||||
/**
|
||||
* Listen to window resize event
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
windowScroll?: boolean
|
||||
|
||||
/**
|
||||
* Listen to window scroll event
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
windowResize?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactive mouse position related to an element.
|
||||
*
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { MouseInElementOptions } from '@vueuse/core'
|
||||
|
||||
import { useElectronMouseInElement } from '../use-electron-mouse-in-element'
|
||||
|
||||
export function useElectronMouseInWindow(
|
||||
options: MouseInElementOptions = {},
|
||||
) {
|
||||
return useElectronMouseInElement(undefined, options)
|
||||
}
|
||||
@@ -10,50 +10,55 @@ import ControlsIsland from '../components/Widgets/ControlsIsland/index.vue'
|
||||
import ResourceStatusIsland from '../components/Widgets/ResourceStatusIsland/index.vue'
|
||||
|
||||
import { electron } from '../../shared/electron'
|
||||
import { useElectronEventaInvoke, useElectronMouseInElement, useElectronRelativeMouse } from '../composables/electron-vueuse'
|
||||
import {
|
||||
useElectronEventaInvoke,
|
||||
useElectronMouseInElement,
|
||||
useElectronMouseInWindow,
|
||||
useElectronRelativeMouse,
|
||||
} from '../composables/electron-vueuse'
|
||||
import { useWindowStore } from '../stores/window'
|
||||
|
||||
const resourceStatusIslandRef = ref<InstanceType<typeof ResourceStatusIsland>>()
|
||||
const controlsIslandRef = ref<InstanceType<typeof ControlsIsland>>()
|
||||
const widgetStageRef = ref<{ canvasElement: () => HTMLCanvasElement }>()
|
||||
const stageCanvas = toRef(() => widgetStageRef.value?.canvasElement())
|
||||
const isClickThrough = ref(false)
|
||||
const isPassingThrough = ref(false)
|
||||
const isLoading = ref(true)
|
||||
const componentStateStage = ref<'pending' | 'loading' | 'mounted'>('pending')
|
||||
|
||||
const { x: relativeMouseX, y: relativeMouseY } = useElectronRelativeMouse()
|
||||
const isTransparent = useCanvasPixelIsTransparentAtPoint(stageCanvas, relativeMouseX, relativeMouseY)
|
||||
const setIgnoreMouseEvents = useElectronEventaInvoke(electron.window.setIgnoreMouseEvents)
|
||||
const isLoading = ref(true)
|
||||
|
||||
const isIgnoringMouseEvents = ref(false)
|
||||
const shouldFadeOnCursorWithin = ref(false)
|
||||
|
||||
const { isOutside: isOutsideWindow } = useElectronMouseInWindow()
|
||||
const { isOutside } = useElectronMouseInElement(controlsIslandRef)
|
||||
const isOutsideFor250Ms = debouncedRef(isOutside, 250)
|
||||
const { x: relativeMouseX, y: relativeMouseY } = useElectronRelativeMouse()
|
||||
const isTransparent = useCanvasPixelIsTransparentAtPoint(stageCanvas, relativeMouseX, relativeMouseY)
|
||||
|
||||
const setIgnoreMouseEvents = useElectronEventaInvoke(electron.window.setIgnoreMouseEvents)
|
||||
|
||||
const { scale, positionInPercentageString } = storeToRefs(useLive2d())
|
||||
const { live2dLookAtX, live2dLookAtY } = storeToRefs(useWindowStore())
|
||||
|
||||
watch(componentStateStage, () => isLoading.value = componentStateStage.value !== 'mounted', { immediate: true })
|
||||
|
||||
const { pause, resume } = watchPausable(isTransparent, (transparent) => {
|
||||
isClickThrough.value = transparent
|
||||
isPassingThrough.value = !transparent
|
||||
shouldFadeOnCursorWithin.value = !transparent
|
||||
}, { immediate: true })
|
||||
|
||||
if (isPassingThrough.value) {
|
||||
setIgnoreMouseEvents([true, { forward: true }])
|
||||
}
|
||||
else {
|
||||
setIgnoreMouseEvents([false, { forward: true }])
|
||||
}
|
||||
})
|
||||
|
||||
watch(isOutsideFor250Ms, () => {
|
||||
watch([isOutsideFor250Ms, isOutsideWindow], () => {
|
||||
if (!isOutsideFor250Ms.value) {
|
||||
isClickThrough.value = false
|
||||
isPassingThrough.value = false
|
||||
isIgnoringMouseEvents.value = false
|
||||
shouldFadeOnCursorWithin.value = false
|
||||
setIgnoreMouseEvents([false, { forward: true }])
|
||||
pause()
|
||||
}
|
||||
else {
|
||||
isClickThrough.value = true
|
||||
isPassingThrough.value = true
|
||||
isIgnoringMouseEvents.value = true
|
||||
if (!isOutsideWindow.value && !isTransparent.value) {
|
||||
shouldFadeOnCursorWithin.value = true
|
||||
}
|
||||
|
||||
setIgnoreMouseEvents([true, { forward: true }])
|
||||
resume()
|
||||
}
|
||||
@@ -77,7 +82,7 @@ watch(isOutsideFor250Ms, () => {
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
isPassingThrough && !isClickThrough ? 'op-0' : 'op-100',
|
||||
shouldFadeOnCursorWithin ? 'op-0' : 'op-100',
|
||||
'absolute',
|
||||
'top-0 left-0 w-full h-full',
|
||||
'transition-opacity duration-250 ease-in-out',
|
||||
|
||||
Reference in New Issue
Block a user