vue实现悬浮球效果

本文实例为大家分享了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);
                /* 过渡效果在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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue实现吸壁悬浮球

    本文实例为大家分享了vue实现吸壁悬浮球的具体代码,供大家参考,具体内容如下 最近接到一个需求,需要一个客服悬浮按钮,可以拖拽并吸壁到页面周边,我们一起看看吧 1.创建一个template,定义客服按钮,自定义v-drag指令 <template>   <div class="container">     <div       class="btn"       id="btn"       :style=&quo

  • Vue.Draggable实现拖拽效果

    快速实现Vue.Draggable的拖拽效果,供大家参考,具体内容如下 1.下载包:npm install vuedraggable 配置:package.json "dependencies": { "element-ui": "^1.3.4", "less": "^2.7.2", "less-loader": "^4.0.4", "vue":

  • 基于Vue实现拖拽功能

    本文实例为大家分享了Vue实现拖拽功能的具体代码,供大家参考,具体内容如下 效果图: HTML代码: <div id="box"> 位置 <br>x:{{val.x}} <br>y:{{val.y}} <div v-drag="greet" id="drag" :style="style"> //注意这里要通过指令绑定函数将当前元素的位置数据传出来 </div> &l

  • 基于Vue实现拖拽效果

    效果图 demo1.gif 分清clientY pageY screenY layerY offsetY的区别 在我们想要做出拖拽这个效果的时候,我们需要分清这几个属性的区别,这几个属性都是计算鼠标点击的偏移值,我们需要对其进行了解才可以继续实现我们的拖拽效果 clientY 指的是距离可视页面左上角的距离 pageY 指的是距离可视页面左上角的距离(不受页面滚动影响) screenY 指的是距离屏幕左上角的距离 layerY 指的是找到它或它父级元素中最近具有定位的左上角距离 offsetY

  • vue实现带自动吸附功能的悬浮球

    本文实例为大家分享了vue实现带自动吸附功能的悬浮球,供大家参考,具体内容如下 封装的组件代码,可以引到页面直接使用 <template>   <div     ref="floatDrag"     class="float-position"     :style="{ left: left + 'px', top: top + 'px', zIndex: zIndex }"     @touchmove.prevent  

  • Vue使用vue-drag-resize生成悬浮拖拽小球

    本文实例为大家分享了使用vue-drag-resize生成悬浮拖拽小球的具体代码,供大家参考,具体内容如下 一.下载依赖 cnpm install  vue-drag-resize 二.main.js引用 import VueDragResize from 'vue-drag-resize' Vue.component('vue-drag-resize', VueDragResize) 三.创建组件 <template>   <vue-drag-resize id="moreM

  • vue使用drag与drop实现拖拽的示例代码

    在功能中有一项是需要实现拖拽的.虽然最终项目没有采取这样的拖拽方式,但是,当初也是费了九牛二虎之力完成了这个功能.增加了对函数的更深理解.下面就再重现一下代码. 下面是代码片段: <div class="fav-fold-panel" v-if="!typeChange" draggable="true" @dragstart="drag($event)" @dragover="allowDrop($event

  • Vue自定义指令拖拽功能示例

    下面给大家分享vue自定义指令拖拽功能代码,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>实例方法</title> <meta name="viewport" content="width=device-width, initial-scale=1

  • vue实现div拖拽互换位置

    本文实例为大家分享了vue实现div拖拽互换位置的具体代码,供大家参考,具体内容如下 template模板 <transition-group tag="div" class="container"> <div class="item" v-for="(item,index) in items" :key="item.key" :style="{background:item.c

  • vue悬浮可拖拽悬浮按钮的实例代码

    前言 vue开发手机端悬浮按钮实现,可以拖拽,滚动的时候收到里边,不影响视线 github地址 使用,基于vue-cli3.0+webpack 4+vant ui + sass+ rem适配方案+axios封装,构建手机端模板脚手架 vue-h5-template 后续将发布各种商城组件组件,让商城简单高效开发 线上体验 使用 将 src/components文件夹下的s-icons组件放到你的组件目录下 使用组件 // template <template> <div> <

随机推荐