canvas/pages/index/utils.js
2025-05-09 11:05:18 +08:00

79 lines
1.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ref, onMounted, onUnmounted } from 'vue'
export function useElementSize(targetSelector) {
const width = ref(0)
const height = ref(0)
let observer = null
const updateSize = () => {
const query = uni.createSelectorQuery()
query.select(targetSelector).boundingClientRect(rect => {
if (rect) {
width.value = rect.width
height.value = rect.height
}
}).exec()
}
onMounted(() => {
updateSize()
// 尝试使用 ResizeObserver部分小程序基础库支持
if (uni.createIntersectionObserver) {
observer = uni.createIntersectionObserver(this, {
observeAll: true
})
observer.relativeToViewport().observe(targetSelector, updateSize)
}
})
onUnmounted(() => {
observer?.disconnect()
})
return { width, height, updateSize }
}
export function useEventListener(target, event, handler) {
// 组件内事件
if (target.$on) {
target.$on(event, handler)
const stop = () => target.$off(event, handler)
onUnmounted(stop)
return stop
}
// 全局事件(需配合 uni.$emit 使用)
else {
uni.$on(event, handler)
const stop = () => uni.$off(event, handler)
onUnmounted(stop)
return stop
}
}
export function useRafFn(fn, { immediate = true } = {}) {
let isActive = false
let timerId = null
const loop = () => {
if (!isActive) return
fn()
timerId = setTimeout(loop, 16) // 模拟 60fps
}
const start = () => {
if (isActive) return
isActive = true
loop()
}
const stop = () => {
isActive = false
clearTimeout(timerId)
}
onUnmounted(stop)
immediate && start()
return { start, stop }
}