Vue利用相反數(shù)實(shí)現(xiàn)飄窗動(dòng)畫(huà)效果
前言
飄窗,即一個(gè)類(lèi)似小窗子的在網(wǎng)頁(yè)上移動(dòng)的矩形元素,通常被用于一些通知類(lèi)的應(yīng)用場(chǎng)景, 飄窗與橫幅相比,更顯眼更具有強(qiáng)調(diào)感和動(dòng)畫(huà)感,在視覺(jué)上更有沖擊性,在體驗(yàn)上互動(dòng)性也更強(qiáng)。
先看下效果圖
實(shí)現(xiàn)思路與分析
1.畫(huà)一個(gè)矩形元素作為飄窗,并使用固定定位
css 繪制一個(gè)固定寬高的矩形,并使用 position:fixed,利用固定定位便于飄窗在屏幕任意位置移動(dòng)。
<div v-if="show" @mouseover="mouseover" @mouseout="mouseout" class="box" :style="{'top':top + 'px','left':left + 'px'}"> <span @click="close">關(guān)閉</span> <div> 特別提示:這僅僅是一個(gè)測(cè)試,不要慌。 </div> </div>
2.編寫(xiě)初始化函數(shù),設(shè)定飄窗初始化規(guī)則
設(shè)置最大的top和left值 = 根元素可視區(qū)域?qū)捀?- 飄窗的寬高 - 邊距
this.maxTop = document.documentElement.clientHeight - 150 - 20 this.maxLeft = document.documentElement.clientWidth - 200 - 20
設(shè)置移動(dòng)規(guī)則:分別設(shè)置水平方向和垂直方向兩個(gè)步長(zhǎng) stepX 和 stepY,設(shè)置兩個(gè)步長(zhǎng)是為了分別利用其相反數(shù)以實(shí)現(xiàn)忘相反方向移動(dòng)的目的: 即是當(dāng)遇到水平方向的邊界時(shí),stepX = -stepX;遇到垂直方向的邊界時(shí),stepY = -stepY。
絕妙啊,這個(gè)相反數(shù)的應(yīng)用,如果不用相反數(shù)該咋寫(xiě)?歡迎評(píng)論區(qū)分享
move () { if (this.top >= this.maxTop || this.top < 0) { this.stepY = -this.stepY } if (this.left >= this.maxLeft || this.left < 0) { this.stepX = -this.stepX } this.top += this.stepY this.left += this.stepX },
3.鼠標(biāo)懸浮在飄窗時(shí)停止移動(dòng)
利用 onmouseover 事件,鼠標(biāo)懸浮在飄窗時(shí),清除定時(shí)器也就是停止了 top 和 left 的值的變更也就是停止了飄窗的移動(dòng)。
mouseover () { clearInterval(this.timer) },
4.鼠標(biāo)離開(kāi)飄窗時(shí)繼續(xù)移動(dòng)
利用 onmouseout 事件,當(dāng)鼠標(biāo)離開(kāi)飄窗時(shí),再利用定時(shí)器,繼續(xù)變更 top 和 left,也就是繼續(xù)移動(dòng)飄窗。 注意開(kāi)啟定時(shí)器前清除下定時(shí)器,這一步是為了保證只有一個(gè)定時(shí)器會(huì)讓飄窗移動(dòng)。 因?yàn)?top 和 left,在飄窗停止移動(dòng)式并沒(méi)有改變,所以能很好地延續(xù)了移動(dòng)路線(xiàn)。
mouseout () { clearInterval(this.timer) this.timer = setInterval(() => { this.move() }, 20) },
5.關(guān)閉飄窗
關(guān)閉飄窗做兩件事,一是令 v-if 的值為 false,即設(shè)置飄窗元素不可見(jiàn)(移除元素);二是清除定時(shí)器。
close () { clearInterval(this.timer) this.show = false },
6.監(jiān)聽(tīng)窗口的大小
window.onresize 監(jiān)聽(tīng)瀏覽器窗口的大小,窗口大小被改變時(shí)調(diào)用飄窗初始化函數(shù) init(),重置飄窗。
onresize () { const that = this window.onresize = function () { that.init() } },
完整 demo 示例
<template> <div> <h1>飄窗 demo</h1> <div v-if="show" @mouseover="mouseover" @mouseout="mouseout" class="box" :style="{'top':top + 'px','left':left + 'px'}"> <span @click="close">關(guān)閉</span> <div> 特別提示:這僅僅是一個(gè)測(cè)試,不要慌。 </div> </div> </div> </template> <script> export default { name: 'MoveWindow', data () { return { show: true, // 是否展現(xiàn)飄窗 stepX: 1, // 水平方向的步長(zhǎng) stepY: 1, // 垂直方向的步長(zhǎng) timer: null, // 定時(shí)器 maxTop: 0, // 最大的 top 值 maxLeft: 0, // 最大的 left 值 top: 0, left: 0, } }, mounted () { this.init() }, beforeDestroy () { // dom 銷(xiāo)毀前清除定時(shí)器 clearInterval(this.timer) }, methods: { // 初始化飄窗規(guī)則 init () { // 設(shè)置最大的top和left值:根元素可視區(qū)域?qū)捀?- 飄窗的寬高 - 邊距 this.maxTop = document.documentElement.clientHeight - 150 - 20 this.maxLeft = document.documentElement.clientWidth - 200 - 20 // 設(shè)置 top 和 left 的初始值 this.top = 0 this.left = 0 // 創(chuàng)建定時(shí)器前清除定時(shí)器,避免類(lèi)似在 onresize 中調(diào)用 init() 時(shí),產(chǎn)生多個(gè)定時(shí)器 clearInterval(this.timer) this.timer = setInterval(() => { this.move() }, 20) this.onresize() }, // 移動(dòng)函數(shù) move () { if (this.top >= this.maxTop || this.top < 0) { this.stepY = -this.stepY } if (this.left >= this.maxLeft || this.left < 0) { this.stepX = -this.stepX } this.top += this.stepY this.left += this.stepX }, // 鼠標(biāo)懸浮在飄窗時(shí)停止移動(dòng) mouseover () { clearInterval(this.timer) }, // 鼠標(biāo)離開(kāi)飄窗時(shí)恢復(fù)移動(dòng) mouseout () { clearInterval(this.timer) this.timer = setInterval(() => { this.move() }, 20) }, // 關(guān)閉飄窗 close () { clearInterval(this.timer) this.show = false }, // 窗口大小調(diào)整時(shí)重置飄窗規(guī)則 onresize () { const that = this window.onresize = function () { that.init() } }, } } </script> <style scoped lang="scss"> .box { background: #9cdf65; width: 200px; height: 150px; border-radius: 5px; position: fixed; text-align: left; padding: 10px; color: #ffffff; top: 0; left: 0; > span { text-align: right; position: absolute; right: 10px; top: 10px; color: #1e87f0; cursor: pointer; } > div { margin-top: 30px; } } </style>
以上就是Vue利用相反數(shù)實(shí)現(xiàn)飄窗動(dòng)畫(huà)效果的詳細(xì)內(nèi)容,更多關(guān)于Vue飄窗動(dòng)畫(huà)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue分頁(yè)查詢(xún)?cè)趺磳?shí)現(xiàn)
這篇文章主要介紹了Vue分頁(yè)查詢(xún)?cè)趺磳?shí)現(xiàn),使用vue實(shí)現(xiàn)分頁(yè)的邏輯并不復(fù)雜,接收后端傳輸過(guò)來(lái)的數(shù)據(jù),然后根據(jù)數(shù)據(jù)的總數(shù)和每一頁(yè)的數(shù)據(jù)量就可以計(jì)算出一共可以分成幾頁(yè)2023-04-04詳解VUE 對(duì)element-ui中的ElTableColumn擴(kuò)展
本篇文章主要介紹了詳解VUE 對(duì)element-ui中的ElTableColumn擴(kuò)展,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03vue對(duì)象復(fù)制方式(深拷貝,多層對(duì)象拷貝方式在后面)
這篇文章主要介紹了vue對(duì)象復(fù)制方式(深拷貝,多層對(duì)象拷貝方式在后面),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09vue實(shí)現(xiàn)彈窗引用另一個(gè)頁(yè)面窗口
這篇文章主要介紹了vue實(shí)現(xiàn)彈窗引用另一個(gè)頁(yè)面窗口,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue+axios+java實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了vue+axios+java實(shí)現(xiàn)文件上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06vue數(shù)據(jù)操作之點(diǎn)擊事件實(shí)現(xiàn)num加減功能示例
這篇文章主要介紹了vue數(shù)據(jù)操作之點(diǎn)擊事件實(shí)現(xiàn)num加減功能,結(jié)合實(shí)例形式分析了vue.js事件響應(yīng)及數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2019-01-01antd中table展開(kāi)行默認(rèn)展示,且不需要前邊的加號(hào)操作
這篇文章主要介紹了antd中table展開(kāi)行默認(rèn)展示,且不需要前邊的加號(hào)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11