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