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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章