本文实例为大家分享了vue实现悬浮球效果的具体代码,供大家参考,具体内容如下
小球效果
小球移动效果图源码
<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: {
// 球名字默认:“球”
text: {
type: String,
default: "ball"
},
// 球宽度默认:“40”
itemWidth: {
type: Number,
default: 40
},
// 球高度默认:“40”
itemHeight: {
type: Number,
default: 40
}
},
data() {
return {
left: 0, // 距离左边距离
top: 0, // 距离抬头距离
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: {
// 点击小球事件
onclick() {
console.log("I am a small clouds");
},
// 开始移动方法
handleTouchStart() {
this.startToMove = true;
this.$refs.breathing_lamp.style.transition = "none";
},
// 移动中方法
handleTouchMove(e) {
const clientX = e.targetTouches[0].clientX; //手指相对视口的x
const clientY = e.targetTouches[0].clientY; //手指相对视口的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; //不让贴边 所以设置30没设置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; //不上帖上边所以设置为30 没设置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已限制此网页运行脚本或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);
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'
// 标记是拖曳还是点击
var isClick = true
var disX, disY, left, top, starX, starY
drag.addEventListener(startEvt, function(e) {
// 阻止页面的滚动,缩放
e.preventDefault()
// 兼容IE浏览器
var e = e || window.event
isClick = true
// 手指按下时的坐标
starX = e.touches ? e.touches[0].clientX : e.clientX
starY = e.touches ? e.touches[0].clientY : e.clientY
// 手指相对于拖动元素左上角的位置
disX = starX - drag.offsetLeft
disY = starY - drag.offsetTop
// 按下之后才监听后续事件
document.addEventListener(moveEvt, moveFun)
document.addEventListener(endEvt, endFun)
})
function moveFun(e) {
// 兼容IE浏览器
var e = e || window.event
// 防止触摸不灵敏,拖动距离大于20像素就认为不是点击,小于20就认为是点击跳转
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) { // 点击
window.location.href = dragLink
}
}
}
</script>
<script>
// 使用说明
// 引入suspension-ball.js,调用suspensionBall()方法,第一个参数传要拖动元素的id,第二个参数传点击后的跳转链接
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%; // 背景图片适应外边框大小
}
</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; //手指相对视口的x
const clientY = e.targetTouches[0].clientY; //手指相对视口的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; //不让贴边 所以设置30没设置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; //不上帖上边所以设置为30 没设置0
} else if (this.top + this.itemHeight > this.clientH) {
this.top = this.clientH - this.itemHeight - 30; //不让帖下边所以减30
}
}
}
};
</script>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。