Vue利用相反數(shù)實(shí)現(xiàn)飄窗動畫效果
前言
飄窗,即一個類似小窗子的在網(wǎng)頁上移動的矩形元素,通常被用于一些通知類的應(yīng)用場景, 飄窗與橫幅相比,更顯眼更具有強(qiáng)調(diào)感和動畫感,在視覺上更有沖擊性,在體驗(yàn)上互動性也更強(qiáng)。
先看下效果圖

實(shí)現(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ù)以實(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ù)移動飄窗。 注意開啟定時器前清除下定時器,這一步是為了保證只有一個定時器會讓飄窗移動。 因?yàn)?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ù)實(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-03
vue對象復(fù)制方式(深拷貝,多層對象拷貝方式在后面)
這篇文章主要介紹了vue對象復(fù)制方式(深拷貝,多層對象拷貝方式在后面),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
vue+axios+java實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了vue+axios+java實(shí)現(xiàn)文件上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06
vue數(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-01
antd中table展開行默認(rèn)展示,且不需要前邊的加號操作
這篇文章主要介紹了antd中table展開行默認(rèn)展示,且不需要前邊的加號操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11

