最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Vue3實(shí)現(xiàn)簡單的鼠標(biāo)跟隨效果

 更新時間:2025年09月08日 16:37:04   作者:Xiecj  
鼠標(biāo)跟隨效果是一種能顯著提升頁面交互性、增加動態(tài)感與趣味性的常見方式,本文將使用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 變量。
  • topleft、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)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue-router3.x和vue-router4.x相互影響的問題分析

    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)路由的示例

    本篇文章主要介紹了vue用addRoutes實(shí)現(xiàn)動態(tài)路由的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • BuildAdmin elementPlus自定義表頭添加tooltip方法示例

    BuildAdmin elementPlus自定義表頭添加tooltip方法示例

    這篇文章主要介紹了BuildAdmin elementPlus 自定義表頭,添加tooltip實(shí)現(xiàn)方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Vue中v-bind原理深入探究

    Vue中v-bind原理深入探究

    這篇文章主要給大家分享了 v-bind的使用和注意需要注意的點(diǎn),下面文章圍繞 v-bind指令的相關(guān)資料展開內(nèi)容且附上詳細(xì)代碼 需要的小伙伴可以參考一下,希望對大家有所幫助
    2022-10-10
  • Vue3中unref的寫法代碼示例

    Vue3中unref的寫法代碼示例

    Vue3中多種響應(yīng)式實(shí)現(xiàn)方式,包括ref、unref、isRef、reactive等,這篇文章主要介紹了Vue3中unref寫法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-06-06
  • 一文帶你了解Vue數(shù)組的變異方法

    一文帶你了解Vue數(shù)組的變異方法

    Vue框架提供了一些便捷的數(shù)組變異方法,包括push、pop、shift、unshift、splice、sort和reverse等,Vue的數(shù)組變異方法可以自動觸發(fā)DOM更新,本文就詳細(xì)帶大家了解一下Vue.js數(shù)組的變異方法
    2023-06-06
  • vue中echarts自動輪播tooltip問題

    vue中echarts自動輪播tooltip問題

    這篇文章主要介紹了vue中echarts自動輪播tooltip問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 聊聊vue集成sweetalert2提示組件的問題

    聊聊vue集成sweetalert2提示組件的問題

    這篇文章主要介紹了vue 集成 sweetalert2 提示組件的問題,本文通過項(xiàng)目案例實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11
  • vue中如何使用ztree

    vue中如何使用ztree

    這篇文章主要介紹了vue中如何使用ztree,包括配置package.json,自動加載jquery的方法,本文給大家介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下
    2018-02-02
  • 利用Vite搭建Vue3+ElementUI-Plus項(xiàng)目的全過程

    利用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

最新評論

永和县| 长沙县| 扶沟县| 大冶市| 冀州市| 蒙山县| 大港区| 连城县| 金山区| 承德县| 江都市| 安宁市| 深州市| 江阴市| 新兴县| 改则县| 长海县| 七台河市| 本溪| 靖江市| 莆田市| 阿拉善盟| 宁城县| 恭城| 改则县| 会昌县| 邹平县| 杨浦区| 三门县| 太仓市| 淳安县| 顺平县| 阿瓦提县| 海口市| 辽阳县| 赫章县| 诏安县| 申扎县| 和田市| 乐平市| 星子县|