使用Vue3實(shí)現(xiàn)簡單的鼠標(biāo)跟隨效果
1. 創(chuàng)建組件基本結(jié)構(gòu)
首先,創(chuàng)建一個 Vue3 組件,我們把它命名為 PageCursor.vue。基本結(jié)構(gòu)如下:
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
const props = withDefaults(defineProps<{
hideCursorSelector?: string | string[]
}>(), {
hideCursorSelector: '.hide-page-cursor'
})
const cursor = ref<HTMLElement | null>(null)
const cursorType = ref('auto')
const cursorState = ref('')
onMounted(() => {})
onUnmounted(() => {})
</script>
<template>
<div
ref="cursor"
class="page-cursor"
:class="[cursorType, cursorState]"
></div>
</template>
<style lang="scss" scoped>
.page-cursor {
--cursor-size: 20px;
position: fixed;
z-index: 9999;
top: calc(-1 * var(--cursor-size) / 2);
left: calc(-1 * var(--cursor-size) / 2);
width: var(--cursor-size);
height: var(--cursor-size);
border-radius: 50%;
backdrop-filter: invert(100%);
pointer-events: none;
opacity: 0;
}
</style>
在組件中,我們定義了 props 對象、三個響應(yīng)式對象和一個 page-cursor 樣式類
props 對象用于接收參數(shù)。使用 props 傳參可以在外部引用組件時控制組件的樣式或行為,這里我們只定義了一個 hideCursorSelector 參數(shù)用于設(shè)置隱藏光標(biāo)這個行為。
三個響應(yīng)式對象分別是:
cursor:跟隨鼠標(biāo)運(yùn)動的光標(biāo)元素。cursorType:光標(biāo)的類型。cursorState:光標(biāo)的狀態(tài)。
page-cursor 樣式類:
--cursor-size:主要是設(shè)置光標(biāo)的大小,后續(xù)有多個地方會用到,所以將其定義為 CSS 變量。top、left、width、height:基于--cursor-size變量進(jìn)行位置和大小的設(shè)置。backdrop-filter:將其值設(shè)置為invert(100%)為光標(biāo)后面區(qū)域添加反色效果。pointer-events:將其值設(shè)置為none來禁用光標(biāo)的指針事件,使其不會影響頁面上其他元素的交互。
2. 添加鼠標(biāo)響應(yīng)事件
添加鼠標(biāo)響應(yīng)事件(移動、按下、彈起)并在組件掛載時注冊事件,在組件卸載時移除事件:
function onMousemove() {}
function onMousedown() {}
function onMouseup() {}
onMounted(() => {
document.addEventListener('mousemove', onMousemove)
document.addEventListener('mousedown', onMousedown)
document.addEventListener('mouseup', onMouseup)
})
onUnmounted(() => {
document.removeEventListener('mousemove', onMousemove)
document.removeEventListener('mousedown', onMousedown)
document.removeEventListener('mouseup', onMouseup)
})
3. 實(shí)現(xiàn)具體功能
在 onMousedown 和 onMouseup 中修改光標(biāo)狀態(tài):
function onMousedown() {
cursorState.value = 'pressed'
}
function onMouseup() {
cursorState.value = ''
}
在 onMousemove 事件中獲取鼠標(biāo)位置,并在 requestAnimationFrame 方法中進(jìn)行更新位置:
let myReq: number = 0
function onMousemove(event: MouseEvent) {
if(!cursor.value) return
cancelAnimationFrame(myReq)
const { clientX, clientY } = event
const target = event.target as HTMLElement
myReq = requestAnimationFrame(() => {
const style = cursor.value!.style
style.transform = `translate3d(${clientX}px, ${clientY}px, 0)`
cursorType.value = getComputedStyle(target)?.cursor || 'auto'
const hideCursorSelectorList = Array.isArray(props.hideCursorSelector)
? props.hideCursorSelector
: [props.hideCursorSelector]
const hideCursor = hideCursorSelectorList.some(item => target.closest(item) !== null)
style.opacity = hideCursor ? '0' : '1'
style.transition = hideCursor ? '0.2s ease-out' : '0.125s ease-out'
})
}
在這段代碼中,首先使用 cancelAnimationFrame 方法關(guān)閉之前創(chuàng)建的動畫幀任務(wù)。然后獲取當(dāng)前鼠標(biāo)的坐標(biāo)和指向的元素。利用 requestAnimationFrame 方法在下一幀渲染前進(jìn)行樣式設(shè)置,以防止在同一幀內(nèi)執(zhí)行多次樣式設(shè)置。并使用 getComputedStyle 方法獲取當(dāng)前鼠標(biāo)指向元素的 CSS 屬性,并從中獲取鼠標(biāo)指針的類型。
最后,將 hideCursorSelector 格式化為 hideCursorSelectorList,通過檢查鼠標(biāo)指向元素與 hideCursorSelectorList 匹配特定選擇器且離當(dāng)前元素最近的祖先元素是否存在來判斷是否隱藏光標(biāo)。
4. 光標(biāo)的狀態(tài)設(shè)置
.page-cursor {
// 其他 page-cursor 樣式
// 鼠標(biāo)光標(biāo)類型為指針時
&.pointer {
--cursor-size: 40px;
// 指針類型并且按下時
&.pressed {
--cursor-size: 20px;
}
}
// 默認(rèn)類型按下時
&.pressed {
--cursor-size: 10px;
}
}
你還可以在不同的鼠標(biāo)事件中對 cursorState 和 cursorType 進(jìn)行賦值,并對 page-cursor 樣式類進(jìn)行更多的定義,來實(shí)現(xiàn)更多光標(biāo)形態(tài)的展示。
5. 完整代碼
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
const props = withDefaults(defineProps<{
hideCursorSelector?: string | string[]
}>(), {
hideCursorSelector: '.hide-page-cursor'
})
const cursor = ref<HTMLElement | null>(null)
const cursorType = ref('auto')
const cursorState = ref('')
let myReq: number = 0
function onMousemove(event: MouseEvent) {
if(!cursor.value) return
cancelAnimationFrame(myReq)
const { clientX, clientY } = event
const target = event.target as HTMLElement
myReq = requestAnimationFrame(() => {
const style = cursor.value!.style
style.transform = `translate3d(${clientX}px, ${clientY}px, 0)`
cursorType.value = getComputedStyle(target)?.cursor || 'auto'
const hideCursorSelectorList = Array.isArray(props.hideCursorSelector)
? props.hideCursorSelector
: [props.hideCursorSelector]
const hideCursor = hideCursorSelectorList.some(item => target.closest(item) !== null)
style.opacity = hideCursor ? '0' : '1'
style.transition = hideCursor ? '0.2s ease-out' : '0.125s ease-out'
})
}
function onMousedown() {
cursorState.value = 'pressed'
}
function onMouseup() {
cursorState.value = ''
}
onMounted(() => {
globalThis.document.addEventListener('mousemove', onMousemove)
globalThis.document.addEventListener('mousedown', onMousedown)
globalThis.document.addEventListener('mouseup', onMouseup)
})
onUnmounted(() => {
globalThis.document.removeEventListener('mousemove', onMousemove)
globalThis.document.removeEventListener('mousedown', onMousedown)
globalThis.document.removeEventListener('mouseup', onMouseup)
})
</script>
<template>
<div
ref="cursor"
class="page-cursor"
:class="[cursorType, cursorState]"
></div>
</template>
<style lang="scss" scoped>
.page-cursor {
--cursor-size: 20px;
position: fixed;
z-index: 9999;
top: calc(-1 * var(--cursor-size) / 2);
left: calc(-1 * var(--cursor-size) / 2);
width: var(--cursor-size);
height: var(--cursor-size);
border-radius: 50%;
backdrop-filter: invert(100%);
pointer-events: none;
opacity: 0;
&.pointer {
--cursor-size: 40px;
&.pressed {
--cursor-size: 20px;
}
}
&.pressed {
--cursor-size: 10px;
}
}
</style>
6.效果圖

到此這篇關(guān)于使用Vue3實(shí)現(xiàn)簡單的鼠標(biāo)跟隨效果的文章就介紹到這了,更多相關(guān)Vue3鼠標(biāo)跟隨內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 基于vue中對鼠標(biāo)劃過事件的處理方式詳解
- vue+mousemove實(shí)現(xiàn)鼠標(biāo)拖動功能(拖動過快失效問題解決方法)
- vue鼠標(biāo)懸停事件實(shí)例詳解
- vue實(shí)現(xiàn)組件跟隨鼠標(biāo)位置彈出效果(示例代碼)
- vue實(shí)現(xiàn)鼠標(biāo)經(jīng)過顯示懸浮框效果
- vue自定義指令添加跟隨鼠標(biāo)光標(biāo)提示框v-tooltip方式
- 如何利用 vue實(shí)現(xiàn)鼠標(biāo)懸停時顯示元素或文本
- Vue中常用的鼠標(biāo)移入移出事件詳解
- 利用Vue3實(shí)現(xiàn)鼠標(biāo)跟隨效果
- vue3實(shí)現(xiàn)鼠標(biāo)跟隨傾斜動態(tài)效果實(shí)例
相關(guān)文章
vue-router3.x和vue-router4.x相互影響的問題分析
這篇文章主要介紹了vue-router3.x和vue-router4.x相互影響的問題分析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04
vue用addRoutes實(shí)現(xiàn)動態(tài)路由的示例
本篇文章主要介紹了vue用addRoutes實(shí)現(xiàn)動態(tài)路由的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
BuildAdmin elementPlus自定義表頭添加tooltip方法示例
這篇文章主要介紹了BuildAdmin elementPlus 自定義表頭,添加tooltip實(shí)現(xiàn)方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
利用Vite搭建Vue3+ElementUI-Plus項(xiàng)目的全過程
vue3如今已經(jīng)成為默認(rèn)版本了,相信大多數(shù)公司已經(jīng)全面擁抱vue3了,下面這篇文章主要給大家介紹了關(guān)于利用Vite搭建Vue3+ElementUI-Plus項(xiàng)目的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07

