vue悬浮球效果
@Herry 人气:0小球效果
小球移动效果图源码
<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); /* 过渡效果在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' // 标记是拖曳还是点击 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>
加载全部内容