vue實(shí)現(xiàn)懸浮球效果
本文實(shí)例為大家分享了vue實(shí)現(xiàn)懸浮球效果的具體代碼,供大家參考,具體內(nèi)容如下
小球效果
小球移動(dòng)效果圖源碼
<template> ? <transition> ? ? <div ? ? ? ref="breathing_lamp" ? ? ? class="breathing_lamp" ? ? ? @click="onclick()" ? ? ? @touchstart.stop="handleTouchStart" ? ? ? @touchmove.prevent.stop="handleTouchMove($event)" ? ? ? @touchend.stop="handleTouchEnd" ? ? ? :style="{left: left + 'px',top: top + 'px',width: itemWidth + 'px',height: itemHeight + 'px'}" ? ? ? v-text="text" ? ? ? v-if="isShow" ? ? >{{text}}</div> ? </transition> </template> <script> export default { ? props: { ? ? // 球名字默認(rèn):“球” ? ? text: { ? ? ? type: String, ? ? ? default: "ball" ? ? }, ? ? // 球?qū)挾饶J(rèn):“40” ? ? itemWidth: { ? ? ? type: Number, ? ? ? default: 40 ? ? }, ? ? // 球高度默認(rèn):“40” ? ? itemHeight: { ? ? ? type: Number, ? ? ? default: 40 ? ? } ? }, ? data() { ? ? return { ? ? ? left: 0, // 距離左邊距離 ? ? ? top: 0, // 距離抬頭距離 ? ? ? startToMove: false, // 開(kāi)始移動(dòng)時(shí)候不顯示 ? ? ? isShow: true, // 組件是否顯示 ? ? ? timer: null, // 定時(shí)器 ? ? ? currentTop: null, // 獲取當(dāng)前頁(yè)面的滾動(dòng)條縱坐標(biāo)位置 ? ? ? clientW: document.documentElement.clientWidth, //視口寬 ? ? ? clientH: document.documentElement.clientHeight //視口高 ? ? }; ? }, ? created() { ? ? // 初始化定義距離四周距離 ? ? this.left = this.clientW - this.itemWidth - 30; ? ? this.top = this.clientH / 2 - this.itemHeight / 2; ? }, ? methods: { ? ? // 點(diǎn)擊小球事件 ? ? onclick() { ? ? ? console.log("I am a small clouds"); ? ? }, ? ? // 開(kāi)始移動(dòng)方法 ? ? handleTouchStart() { ? ? ? this.startToMove = true; ? ? ? this.$refs.breathing_lamp.style.transition = "none"; ? ? }, ? ? // 移動(dòng)中方法 ? ? handleTouchMove(e) { ? ? ? const clientX = e.targetTouches[0].clientX; //手指相對(duì)視口的x ? ? ? const clientY = e.targetTouches[0].clientY; //手指相對(duì)視口的y ? ? ? const isInScreen = ? ? ? ? clientX <= this.clientW && ? ? ? ? clientX >= 0 && ? ? ? ? clientY <= this.clientH && ? ? ? ? clientY >= 0; ? ? ? if (this.startToMove && e.targetTouches.length === 1) { ? ? ? ? if (isInScreen) { ? ? ? ? ? this.left = clientX - this.itemWidth / 2; ? ? ? ? ? this.top = clientY - this.itemHeight / 2; ? ? ? ? } ? ? ? } ? ? }, ? ? // 移動(dòng)結(jié)束方法 ? ? handleTouchEnd() { ? ? ? if (this.left < this.clientW / 2) { ? ? ? ? this.left = 30; //不讓貼邊 所以設(shè)置30沒(méi)設(shè)置0 ? ? ? ? this.handleIconY(); ? ? ? } else { ? ? ? ? this.left = this.clientW - this.itemWidth - 30; //距邊30px ? ? ? ? this.handleIconY(); ? ? ? } ? ? ? this.$refs.breathing_lamp.style.transition = "all .3s"; ? ? }, ? ? // 上下不貼邊方法 ? ? handleIconY() { ? ? ? if (this.top < 0) { ? ? ? ? this.top = 30; //不上帖上邊所以設(shè)置為30 沒(méi)設(shè)置0 ? ? ? } else if (this.top + this.itemHeight > this.clientH) { ? ? ? ? this.top = this.clientH - this.itemHeight - 30; //距邊30px ? ? ? } ? ? } ? } }; </script> <style lang="scss" scoped> .breathing_lamp { ? position: fixed; ? width: 40px; ? height: 40px; ? border-radius: 50%; ? background-color: orange; ? line-height: 40px; ? text-align: center; ? color: #fff; } </style>
html懸浮球
// index.html <!DOCTYPE html> <html lang="en"> ?? ?<!-- 防止IE提示“Internet Explorer已限制此網(wǎng)頁(yè)運(yùn)行腳本或ActiveX控件” --> ?? ?<!-- saved from url=(0014)about:internet --> ?? ?<head> ?? ??? ?<meta charset="UTF-8"> ?? ??? ?<meta name="viewport" content="width=device-width, initial-scale=1.0"> ?? ??? ?<meta http-equiv="X-UA-Compatible" content="ie=edge"> ?? ??? ?<title>Document</title> ?? ??? ?<style> ?? ??? ??? ?#ballId { ?? ??? ??? ??? ?background: rgb(19, 167, 19); ?? ??? ??? ??? ?color: white; ?? ??? ??? ??? ?width: 50px; ?? ??? ??? ??? ?text-align: center; ?? ??? ??? ??? ?height: 50px; ?? ??? ??? ??? ?line-height: 50px; ?? ??? ??? ??? ?border-radius: 50%; ?? ??? ??? ??? ?box-shadow: 5px 5px 40px rgba(0, 0, 0, 0.5); ?? ??? ??? ??? ?/* 過(guò)渡效果在IE下展示效果不友好 */ ?? ??? ??? ??? ?transition: all 0.08s; ?? ??? ??? ??? ?user-select: none; ?? ??? ??? ??? ?-moz-user-select: none; ?? ??? ??? ??? ?-ms-user-select: none; ?? ??? ??? ??? ?-webkit-user-select: none; ?? ??? ??? ??? ?top: 50%; ?? ??? ??? ??? ?left: 50%; ?? ??? ??? ??? ?transform: translate3d(-50%, -50%, 0); ?? ??? ??? ?} ?? ??? ?</style> ?? ?</head> ?? ?<body> ?? ??? ?<div id="ballId">drag</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<div id=""> ?? ??? ??? ?11 ?? ??? ?</div> ?? ??? ?<!-- <script src="./suspension-ball.js"></script> --> ?? ??? ?<script> ?? ??? ??? ?function suspensionBall(dragId, dragLink) { ?? ??? ??? ??? ?var startEvt, moveEvt, endEvt ?? ??? ??? ??? ?// 判斷是否支持觸摸事件 ?? ??? ??? ??? ?if ('ontouchstart' in window) { ?? ??? ??? ??? ??? ?startEvt = 'touchstart' ?? ??? ??? ??? ??? ?moveEvt = 'touchmove' ?? ??? ??? ??? ??? ?endEvt = 'touchend' ?? ??? ??? ??? ?} else { ?? ??? ??? ??? ??? ?startEvt = 'mousedown' ?? ??? ??? ??? ??? ?moveEvt = 'mousemove' ?? ??? ??? ??? ??? ?endEvt = 'mouseup' ?? ??? ??? ??? ?} ?? ??? ??? ??? ?// 獲取元素 ?? ??? ??? ??? ?var drag = document.getElementById(dragId) ?? ??? ??? ??? ?drag.style.position = 'absolute' ?? ??? ??? ??? ?drag.style.cursor = 'move' ?? ??? ??? ??? ?// 標(biāo)記是拖曳還是點(diǎn)擊 ?? ??? ??? ??? ?var isClick = true ?? ??? ??? ??? ?var disX, disY, left, top, starX, starY ?? ??? ??? ??? ?drag.addEventListener(startEvt, function(e) { ?? ??? ??? ??? ??? ?// 阻止頁(yè)面的滾動(dòng),縮放 ?? ??? ??? ??? ??? ?e.preventDefault() ?? ??? ??? ??? ??? ?// 兼容IE瀏覽器 ?? ??? ??? ??? ??? ?var e = e || window.event ?? ??? ??? ??? ??? ?isClick = true ?? ??? ??? ??? ??? ?// 手指按下時(shí)的坐標(biāo) ?? ??? ??? ??? ??? ?starX = e.touches ? e.touches[0].clientX : e.clientX ?? ??? ??? ??? ??? ?starY = e.touches ? e.touches[0].clientY : e.clientY ?? ??? ??? ??? ??? ?// 手指相對(duì)于拖動(dòng)元素左上角的位置 ?? ??? ??? ??? ??? ?disX = starX - drag.offsetLeft ?? ??? ??? ??? ??? ?disY = starY - drag.offsetTop ?? ??? ??? ??? ??? ?// 按下之后才監(jiān)聽(tīng)后續(xù)事件 ?? ??? ??? ??? ??? ?document.addEventListener(moveEvt, moveFun) ?? ??? ??? ??? ??? ?document.addEventListener(endEvt, endFun) ?? ??? ??? ??? ?}) ?? ??? ??? ??? ?function moveFun(e) { ?? ??? ??? ??? ??? ?// 兼容IE瀏覽器 ?? ??? ??? ??? ??? ?var e = e || window.event ?? ??? ??? ??? ??? ?// 防止觸摸不靈敏,拖動(dòng)距離大于20像素就認(rèn)為不是點(diǎn)擊,小于20就認(rèn)為是點(diǎn)擊跳轉(zhuǎn) ?? ??? ??? ??? ??? ?if ( ?? ??? ??? ??? ??? ??? ?Math.abs(starX - (e.touches ? e.touches[0].clientX : e.clientX)) > 20 || ?? ??? ??? ??? ??? ??? ?Math.abs(starY - (e.touches ? e.touches[0].clientY : e.clientY)) > 20 ?? ??? ??? ??? ??? ?) { ?? ??? ??? ??? ??? ??? ?isClick = false ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?left = (e.touches ? e.touches[0].clientX : e.clientX) - disX ?? ??? ??? ??? ??? ?top = (e.touches ? e.touches[0].clientY : e.clientY) - disY ?? ??? ??? ??? ??? ?// 限制拖拽的X范圍,不能拖出屏幕 ?? ??? ??? ??? ??? ?if (left < 0) { ?? ??? ??? ??? ??? ??? ?left = 0 ?? ??? ??? ??? ??? ?} else if (left > document.documentElement.clientWidth - drag.offsetWidth) { ?? ??? ??? ??? ??? ??? ?left = document.documentElement.clientWidth - drag.offsetWidth ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?// 限制拖拽的Y范圍,不能拖出屏幕 ?? ??? ??? ??? ??? ?if (top < 0) { ?? ??? ??? ??? ??? ??? ?top = 0 ?? ??? ??? ??? ??? ?} else if (top > document.documentElement.clientHeight - drag.offsetHeight) { ?? ??? ??? ??? ??? ??? ?top = document.documentElement.clientHeight - drag.offsetHeight ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?drag.style.left = left + 'px' ?? ??? ??? ??? ??? ?drag.style.top = top + 'px' ?? ??? ??? ??? ?} ?? ??? ??? ??? ?function endFun(e) { ?? ??? ??? ??? ??? ?document.removeEventListener(moveEvt, moveFun) ?? ??? ??? ??? ??? ?document.removeEventListener(endEvt, endFun) ?? ??? ??? ??? ??? ?if (isClick) { // 點(diǎn)擊 ?? ??? ??? ??? ??? ??? ?window.location.href = dragLink ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?</script> ?? ??? ?<script> ?? ??? ??? ?// 使用說(shuō)明 ?? ??? ??? ?// 引入suspension-ball.js,調(diào)用suspensionBall()方法,第一個(gè)參數(shù)傳要拖動(dòng)元素的id,第二個(gè)參數(shù)傳點(diǎn)擊后的跳轉(zhuǎn)鏈接 ?? ??? ??? ?suspensionBall('ballId', 'https://www.baidu.com') ?? ??? ?</script> ?? ?</body> </html>
懸浮球添加彈框
<template> ? <div> ? ? <div> ? ? ? <!-- 懸浮球 --> ? ? ? <div ? ? ? ? ref="breathing_lamp" ? ? ? ? class="breathing_lamp" ? ? ? ? @click="show3 = !show3" ? ? ? ? @touchstart.stop="handleTouchStart" ? ? ? ? @touchmove.prevent.stop="handleTouchMove($event)" ? ? ? ? @touchend.stop="handleTouchEnd" ? ? ? ? :style="{left: left + 'px',top: top + 'px',width: itemWidth + 'px',height: itemHeight + 'px'}" ? ? ? ? v-text="text" ? ? ? ? v-if="isShow" ? ? ? ></div> ? ? ? <div id="buttonComBination" v-show="show3" class="collapseTransiton"> ? ? ? ? <el-collapse-transition> ? ? ? ? ? <div class="transitionBoxs" :style="{left: left - 20+ ?'px', top: top + 30+ 'px'}"> ? ? ? ? ? ? <div class="transition-box">返回</div> ? ? ? ? ? ? <div class="transition-box">編輯</div> ? ? ? ? ? ? <div class="transition-box">下一步</div> ? ? ? ? ? </div> ? ? ? ? </el-collapse-transition> ? ? ? ? <!-- <buttonComBination></buttonComBination> --> ? ? ? </div> ? ? </div> ? </div> </template> <style lang="scss" scoped> .transitionBoxs { ? min-height: 100px; ? position: fixed; ? z-index: 1024; ? top: 57%; ? right: 5%; ? border: 1px; ? margin-top: 5%; } .transition-box { ? display: flex; ? justify-content: center; ? align-items: center; ? margin-bottom: 10px; ? height: 30px; ? border-radius: 4px; ? background-color: #409eff; ? color: #fff; ? padding: 10px 10px; ? box-sizing: border-box; ? width: 80px; } // 懸浮球位置 .breathing_lamp { ? // left: var(--left); ? // top: var (--top); ? // width: var(--width); ? // height: var(--height); ? border: 1px; ? border-radius: 50%; ? width: 40px; ? height: 40px; ? position: fixed; ? top: 40%; ? right: 0%; ? z-index: 1024; ? background: url("../../assets/publicAll/cloud.png") no-repeat center center; ? background-size: 100% 100%; // 背景圖片適應(yīng)外邊框大小 } </style> <script> import buttonComBination from "../publicAll/button_comBination"; export default { ? components: { ? ? buttonComBination ? }, ? props: { ? ? text: { ? ? ? type: String, ? ? ? default: "" ? ? }, ? ? itemWidth: { ? ? ? type: Number, ? ? ? default: 40 ? ? }, ? ? itemHeight: { ? ? ? type: Number, ? ? ? default: 40 ? ? } ? }, ? data() { ? ? return { ? ? ? show3: true, ? ? ? cloud: require("../../assets/publicAll/cloud.png"), ? ? ? left: 0, ? ? ? top: 300, ? ? ? startToMove: false, ? ? ? isShow: true, ? ? ? timer: null, ? ? ? currentTop: null, ? ? ? clientW: document.documentElement.clientWidth, //視口寬 ? ? ? clientH: document.documentElement.clientHeight //視口高 ? ? }; ? }, ? created() { ? ? this.left = this.clientW - this.itemWidth - 30; ? ? this.top = this.clientH / 2 - this.itemHeight / 2; ? }, ? methods: { ? ? handleTouchStart() { ? ? ? this.startToMove = true; ? ? ? this.$refs.breathing_lamp.style.transition = "none"; ? ? }, ? ? handleTouchMove(e) { ? ? ? const clientX = e.targetTouches[0].clientX; //手指相對(duì)視口的x ? ? ? const clientY = e.targetTouches[0].clientY; //手指相對(duì)視口的y ? ? ? const isInScreen = ? ? ? ? clientX <= this.clientW && ? ? ? ? clientX >= 0 && ? ? ? ? clientY <= this.clientH && ? ? ? ? clientY >= 0; ? ? ? if (this.startToMove && e.targetTouches.length === 1) { ? ? ? ? if (isInScreen) { ? ? ? ? ? this.left = clientX - this.itemWidth / 2; ? ? ? ? ? this.top = clientY - this.itemHeight / 2; ? ? ? ? } ? ? ? } ? ? }, ? ? handleTouchEnd() { ? ? ? if (this.left < this.clientW / 2) { ? ? ? ? this.left = 30; //不讓貼邊 所以設(shè)置30沒(méi)設(shè)置0 ? ? ? ? this.handleIconY(); ? ? ? } else { ? ? ? ? this.left = this.clientW - this.itemWidth - 30; //不讓貼邊 所以減30 ? ? ? ? this.handleIconY(); ? ? ? } ? ? ? this.$refs.breathing_lamp.style.transition = "all .3s"; ? ? }, ? ? handleIconY() { ? ? ? if (this.top < 0) { ? ? ? ? this.top = 30; //不上帖上邊所以設(shè)置為30 沒(méi)設(shè)置0 ? ? ? } else if (this.top + this.itemHeight > this.clientH) { ? ? ? ? this.top = this.clientH - this.itemHeight - 30; //不讓帖下邊所以減30 ? ? ? } ? ? } ? } }; </script>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue+Element UI 實(shí)現(xiàn)視頻上傳功能
這篇文章主要介紹了Vue+Element UI 實(shí)現(xiàn)視頻上傳功能,前臺(tái)使用Vue+Element UI中的el-upload組件實(shí)現(xiàn)視頻上傳及進(jìn)度條展示,后臺(tái)提供視頻上傳API并返回URL,具體實(shí)現(xiàn)代碼及效果展示跟隨小編一起看看吧2022-01-01Vue.js組件props數(shù)據(jù)驗(yàn)證實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了Vue.js組件props數(shù)據(jù)驗(yàn)證的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10一個(gè)因@click.stop引發(fā)的bug的解決
這篇文章主要介紹了一個(gè)因@click.stop引發(fā)的bug的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01vue監(jiān)聽(tīng)鍵盤事件的相關(guān)總結(jié)
這篇文章主要介紹了vue監(jiān)聽(tīng)鍵盤事件的相關(guān)總結(jié),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01Avue和Element-UI動(dòng)態(tài)三級(jí)表頭的實(shí)現(xiàn)
本文主要介紹了Avue和Element-UI動(dòng)態(tài)三級(jí)表頭的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Vue filter 過(guò)濾當(dāng)前時(shí)間 實(shí)現(xiàn)實(shí)時(shí)更新效果
這篇文章主要介紹了Vue filter 過(guò)濾當(dāng)前時(shí)間 實(shí)現(xiàn)實(shí)時(shí)更新效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12