vue實(shí)現(xiàn)氣泡運(yùn)動撞擊效果
本文實(shí)例為大家分享了vue實(shí)現(xiàn)氣泡運(yùn)動撞擊效果的具體代碼,供大家參考,具體內(nèi)容如下
封裝組件
<template> ? <ul id="main"> ? ? <li v-for="(item, index) in circleData" :key="index" :class="{'active': item.is_latest_sign_user}"> ? ? ? <div> ? ? ? ? <span>{{ item.nick_name }}</span> ? ? ? ? <span>簽到</span> ? ? ? </div> ? ? </li> ? </ul> </template> <script> export default { ? data() { ? ? return { ? ? ? circleData: [], ? ? ? circleDom: [], ? ? ? circleArr: [], ? ? ? //初始化運(yùn)動的最大寬和高,初始定義0 ? ? ? maxW: 0, ? ? ? maxH: 0, ? ? ? timer: null, ? ? ? timerArr: [], ? ? ? count: 0, ? ? }; ? }, ? mounted() { ? ? this.getLatest_sign_users('init') ? ? this.timer = setInterval((i) => { ? ? ? this.count++ ? ? ? this.getLatest_sign_users() ? ? }, 5000) ? }, ? methods: { ? ? getLatest_sign_users(type = '') { ? ? ? let data = [] ? ? ? // nick_name: 用戶名 ? ? ? // is_latest_sign_user: 是否是新簽到用戶 ? ? ? // gender: 0-女 1-男 ? ? ? if (this.count === 0) { ? ? ? ? data = [ ? ? ? ? ? { ? ? ? ? ? ? id: '1', ? ? ? ? ? ? nick_name: '蕭一', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '楊二', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '張三', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 0 ? ? ? ? ? } ? ? ? ? ] ? ? ? } else if (this.count === 1) { ? ? ? ? data = [ ? ? ? ? ? { ? ? ? ? ? ? nick_name: '蕭一', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '楊二', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '張三', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '李四', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '王五', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '徐六', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '劉七', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 1 ? ? ? ? ? } ? ? ? ? ] ? ? ? } else if (this.count === 2) { ? ? ? ? data = [ ? ? ? ? ? { ? ? ? ? ? ? nick_name: '蕭一', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '楊二', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '張三', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '李四', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '王五', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '徐六', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '劉七', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '何八', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '柳九', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '甄十', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '十一', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '十二', ? ? ? ? ? ? is_latest_sign_user: true, ? ? ? ? ? ? gender: 1 ? ? ? ? ? } ? ? ? ? ] ? ? ? } else { ? ? ? ? data = [ ? ? ? ? ? { ? ? ? ? ? ? nick_name: '蕭一', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '楊二', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '張三', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '李四', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '王五', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '徐六', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '劉七', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '何八', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '柳九', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 0 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '甄十', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '十一', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? }, ? ? ? ? ? { ? ? ? ? ? ? nick_name: '十二', ? ? ? ? ? ? is_latest_sign_user: false, ? ? ? ? ? ? gender: 1 ? ? ? ? ? } ? ? ? ? ] ? ? ? } ? ? ? this.circleData = [...data] ? ? ? if (type === 'init') {//初次加載時默認(rèn)全是新增簽到用戶 ? ? ? ? data.forEach(item => item.is_latest_sign_user = true) ? ? ? } ? ? ? this.$nextTick(() => { ? ? ? ? if (data.length) { ? ? ? ? ? this.initBubble() ? ? ? ? } ? ? ? }) ? ? }, ? ? initBubble() { ? ? ? let main = document.getElementById("main"); ? ? ? let divDom = main.getElementsByClassName("active"); //獲取新增加的dom ? ? ? if (!divDom.length) return; ? ? ? //清理每個球得定時器 ? ? ? this.timerArr.forEach(item => { ? ? ? ? clearInterval(item) ? ? ? }) ? ? ? this.timerArr = [] ?? ? ?//給新增加的dom設(shè)置寬高 ? ? ? for (let i = 0; i < divDom.length; i++) { ? ? ? ? let colors = [ ? ? ? ? ? "#EF250A", ? ? ? ? ? "#830AF6" ? ? ? ? ]; ? ? ? ? divDom[i].style.boxShadow = "0 0 20px" + " " + colors[this.circleData[i].gender] + " " + "inset"; ? ? ? ? // 10個以上尺寸變小 ? ? ? ? divDom[i].style.width = "46px"; ? ? ? ? divDom[i].style.height = "46px"; ? ? ? ? divDom[i].style.fontSize = "12px"; ? ? ? ? divDom[i].style.lineHeight = "16px"; ? ? ? ? this.circleDom.push(divDom[i]) ? ? ? } ? ? ? //根據(jù)瀏覽器窗口的大小自動調(diào)節(jié)小球的運(yùn)動空間 ? ? ? window.onresize = () => { ? ? ? ? this.maxW = main.clientWidth - divDom[0].clientWidth; //為了讓小球不卡在瀏覽器邊緣 ? ? ? ? this.maxH = main.clientHeight - divDom[0].clientHeight; // 所以要減去自身的寬高 ? ? ? }; ? ? ? onresize(); ? ? ? //數(shù)組對象的初始化 ? ? ? for (let i = 0; i < this.circleDom.length; i++) { ? ? ? ? let obj = {}; ? ? ? ? console.log(this.circleDom[i]); ? ? ? ? if (this.circleDom[i].getAttribute("class") === 'active') { ? ? ? ? ? obj.x = Math.floor(Math.random() * (this.maxW + 1)); //初始x坐標(biāo) ? ? ? ? ? obj.y = Math.floor(Math.random() * (this.maxH + 1)); //初始y坐標(biāo) ? ? ? ? ? obj.cx = obj.x + this.circleDom[0].offsetWidth / 2;//圓心x坐標(biāo) ? ? ? ? ? obj.cy = obj.y + this.circleDom[0].offsetHeight / 2;//圓心y坐標(biāo) ? ? ? ? ? obj.movex = Math.floor(Math.random() * 2); //x軸移動方向 ? ? ? ? ? obj.movey = Math.floor(Math.random() * 2); //y軸移動方向 ? ? ? ? ? obj.speed = 0.2; //隨機(jī)速度 ? ? ? ? ? obj.timer = null; //計時器 ? ? ? ? ? obj.index = i; //索引值 ? ? ? ? ? this.circleArr.push(obj) ? ? ? ? ? //小球位置初始化 ? ? ? ? ? this.circleDom[i].style.left = obj.x + 'px'; ? ? ? ? ? this.circleDom[i].style.top = obj.y + 'px'; ? ? ? ? } else { ? ? ? ? ? //保留之前數(shù)據(jù)得位置信息,不刷新位置 ? ? ? ? ? obj = this.circleArr[i] ? ? ? ? } ? ? ? ? this.move(obj); ? ? ? } ? ? }, ? ? //移動函數(shù) ? ? move(balls) { ? ? ? //每個球單獨(dú)有定時器 ? ? ? balls.timer = setInterval(() => { ? ? ? ? if (balls.movex === 1) { ? ? ? ? ? //如果往右跑,則一直加速度,碰到邊界,改為反方向運(yùn)動 ? ? ? ? ? balls.x += balls.speed; ? ? ? ? ? if (balls.x + balls.speed >= this.maxW) { ? ? ? ? ? ? //防止小球出界 ? ? ? ? ? ? balls.x = this.maxW; ? ? ? ? ? ? balls.movex = 0; //小球運(yùn)動方向發(fā)生改變 ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? balls.x -= balls.speed; // 1和0表示正反方向 ? ? ? ? ? if (balls.x - balls.speed <= 0) { ? ? ? ? ? ? balls.x = 0; ? ? ? ? ? ? balls.movex = 1; ? ? ? ? ? } ? ? ? ? } ? ? ? ? if (balls.movey === 1) { ? ? ? ? ? balls.y += balls.speed; ? ? ? ? ? if (balls.y + balls.speed >= this.maxH) { ? ? ? ? ? ? balls.y = this.maxH; ? ? ? ? ? ? balls.movey = 0; ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? balls.y -= balls.speed; ? ? ? ? ? if (balls.y - balls.speed <= 0) { ? ? ? ? ? ? balls.y = 0; ? ? ? ? ? ? balls.movey = 1; ? ? ? ? ? } ? ? ? ? } ? ? ? ? if (this.circleDom[balls.index]) { ? ? ? ? ? balls.cx = balls.x + this.circleDom[0].offsetWidth / 2;//小球圓心等于:運(yùn)動中x的值加上自身的半徑 ? ? ? ? ? balls.cy = balls.y + this.circleDom[0].offsetHeight / 2; ? ? ? ? ? this.circleDom[balls.index].style.left = balls.x + "px"; //小球相對于屏幕的位置 ? ? ? ? ? this.circleDom[balls.index].style.top = balls.y + "px"; ? ? ? ? ? this.crash(balls.index); //每個小球進(jìn)行碰撞檢測 ? ? ? ? } ? ? ? }, 25); ? ? ? this.timerArr.push(balls.timer) ? ? }, ? ? //碰撞函數(shù) ? ? crash(a) { ? ? ? let container = [...this.circleArr] ? ? ? let ball1x = container[a].cx; //在數(shù)組中任意球的圓心坐標(biāo) ? ? ? let ball1y = container[a].cy;//思路:先隨便拿一個球,然后遍歷所有球,拿這個球和所有球的圓心距離比較 ? ? ? for (let i = 0; i < container.length; i++) { ? ? ? ? if (i !== a) { //判斷取出來的球不是本身,才能和其他球進(jìn)行距離判斷 ? ? ? ? ? let ball2x = container[i].cx; //將其他球的圓心坐標(biāo)賦值給球2 ? ? ? ? ? let ball2y = container[i].cy; ? ? ? ? ? //圓心距 求兩個點(diǎn)之間的距離,開平方 ? ? ? ? ? let distence = Math.sqrt((ball1x - ball2x) * (ball1x - ball2x) + (ball1y - ball2y) * (ball1y - ball2y)); ? ? ? ? ? if (distence <= this.circleDom[0].offsetWidth) { //球心距離和求直徑比較 ? ? ? ? ? ? if (ball1x > ball2x) { //當(dāng)前位于未知求的右方 ? ? ? ? ? ? ? if (ball1y > ball2y) {//預(yù)設(shè)未知球撞當(dāng)前球,然后當(dāng)前球改變運(yùn)動 ? ? ? ? ? ? ? ? container[a].movex = 1; //1表示為正值,對應(yīng)的右和下 ? ? ? ? ? ? ? ? container[a].movey = 1;//0表示為負(fù)值,對應(yīng)的左和上 ? ? ? ? ? ? ? } else if (ball1y < ball2y) { ? ? ? ? ? ? ? ? container[a].movex = 1; ? ? ? ? ? ? ? ? container[a].movey = 0; ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? container[a].movex = 1; ? ? ? ? ? ? ? } ? ? ? ? ? ? } else if (ball1x < ball2x) { ? ? ? ? ? ? ? if (ball1y > ball2y) { ? ? ? ? ? ? ? ? container[a].movex = 0; ? ? ? ? ? ? ? ? container[a].movey = 0; ? ? ? ? ? ? ? } else if (ball1y < ball2y) { ? ? ? ? ? ? ? ? container[a].movex = 0; ? ? ? ? ? ? ? ? container[a].movey = 1; ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? container[a].movex = 0; ? ? ? ? ? ? ? } ? ? ? ? ? ? } else { ? ? ? ? ? ? ? if (ball1y > ball2y) { ? ? ? ? ? ? ? ? container[a].movey = 1; ? ? ? ? ? ? ? } else if (ball1y < ball2y) { ? ? ? ? ? ? ? ? container[a].movey = 0; ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? } ? }, ? beforeDestroy() { ? ? //清理每個球得定時器 ? ? this.timerArr.forEach(item => { ? ? ? clearInterval(item) ? ? }) ? ? //清理簽到數(shù)據(jù) ? ? clearInterval(this.timer) ? } }; </script> <style lang='less' scoped> #main { ? position: relative; ? width: 100%; ? height: 100%; ? overflow: hidden; ? padding: 0; ? li { ? ? position: absolute; ? ? overflow: hidden; ? ? -moz-border-radius: 50%; ? ? -webkit-border-radius: 50%; ? ? border-radius: 50%; ? ? display: flex; ? ? align-items: center; ? ? justify-content: center; ? ? flex-wrap: wrap; ? ? &.active { ? ? ? animation: scaleBox 1s 1; ? ? } ? ? @keyframes scaleBox { ? ? ? 0% { ? ? ? ? transform: scale(1); ? ? ? } ? ? ? 50% { ? ? ? ? transform: scale(1.2); ? ? ? } ? ? ? 100% { ? ? ? ? transform: scale(1); ? ? ? } ? ? } ? ? div { ? ? ? span { ? ? ? ? display: block; ? ? ? ? width: 100%; ? ? ? ? color: #fff; ? ? ? ? text-align: center; ? ? ? } ? ? } ? } } </style>
實(shí)現(xiàn)效果
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- vue+elementui(對話框中form表單的reset問題)
- vue如何實(shí)現(xiàn)關(guān)閉對話框后刷新列表
- vue3動態(tài)加載對話框的方法實(shí)例
- Vue對話框組件使用方法詳解
- element-ui和vue表單(對話框)驗(yàn)證提示語(殘留)清除操作
- vue+ElementUI 關(guān)閉對話框清空驗(yàn)證,清除form表單的操作
- vue+elementui 對話框取消 表單驗(yàn)證重置示例
- 解決Vue開發(fā)中對話框被遮罩層擋住的問題
- vue實(shí)現(xiàn)element-ui對話框可拖拽功能
- vue中的模態(tài)對話框組件實(shí)現(xiàn)過程
- vue 指令之氣泡提示效果的實(shí)現(xiàn)代碼
- Vue3編寫氣泡對話框組件
相關(guān)文章
vue?router進(jìn)行路由跳轉(zhuǎn)并攜帶參數(shù)的實(shí)例詳解(params/query)
在使用`router.push`進(jìn)行路由跳轉(zhuǎn)到另一個組件時,可以通過`params`或`query`來傳遞參數(shù),這篇文章主要介紹了vue?router進(jìn)行路由跳轉(zhuǎn)并攜帶參數(shù)(params/query),需要的朋友可以參考下2023-09-09vue proxyTable的跨域中pathRewrite配置方式
這篇文章主要介紹了vue proxyTable的跨域中pathRewrite配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04vue項(xiàng)目或網(wǎng)頁上實(shí)現(xiàn)文字轉(zhuǎn)換成語音播放功能
這篇文章主要介紹了在vue項(xiàng)目或網(wǎng)頁上實(shí)現(xiàn)文字轉(zhuǎn)換成語音,需要的朋友可以參考下2020-06-06解決Vue3使用Element-Plus導(dǎo)航刷新后active高亮消失的問題
這篇文章主要給大家介紹了如何解決Vue3使用Element-Plus導(dǎo)航刷新后active高亮消失的問題,文中有相關(guān)的代碼講解,需要的朋友可以參考下2023-08-08echarts實(shí)現(xiàn)獲取datazoom的起始值(包括x軸和y軸)
這篇文章主要介紹了echarts實(shí)現(xiàn)獲取datazoom的起始值(包括x軸和y軸),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07解決Vue.js Devtools未檢測到Vue實(shí)例的問題
在開發(fā)Vue.js應(yīng)用時,Vue.js Devtools是一個不可或缺的調(diào)試工具,然而,有時我們可能會遇到“Vue.js not detected”的提示,這意味著Vue.js Devtools未能成功識別和連接到我們的Vue應(yīng)用,本文將詳細(xì)解析這個問題,并提供相應(yīng)的解決步驟與代碼示例,需要的朋友可以參考下2024-01-01VueX瀏覽器刷新如何實(shí)現(xiàn)保存數(shù)據(jù)
這篇文章主要介紹了VueX瀏覽器刷新如何實(shí)現(xiàn)保存數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07vue.js移動端app實(shí)戰(zhàn)1:初始配置詳解
這篇文章主要介紹了vue.js移動端app實(shí)戰(zhàn)1:初始配置詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07