uni-app 可拖拽移动的悬浮球

1,508 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,查看详情

需求: uni-app 小程序做一个可以随意拖拽移动的悬浮球,而且对性能有一定的要求,不能出现页面卡顿的情况

image.png

开发中发现的问题: 1.引入插件导致页面卡顿。在开发时间紧凑的压力,本想通过找组件快速解决这个问题,在uni-app插件市场找了几个插件都发现引用的包过大,算法复杂导致页面卡顿等等 2. 拖拽超出页面,找不到icon。在随意拖动几次之后发现icon的拖动速度以及距离等等不受控制。

以下就是经过几次错误的写法后得出了完美的一个解决方法:页面不卡顿,而且怎么拖拽都不会超出页面

1.html部分代码

<template>
  <view class="addNumberBox">
    <view class="addNumber"
      :style="'left:'+(moveX == 0 & x>0? x+'%':moveX+'px')+';top:'+(moveY == 0 & y>0? y+'%':moveY+'px')"
      @touchstart="drag_start" @touchmove.prevent="drag_hmove" mode="aspectFit" @click="toAdd">
      新增<p></p>
      物料
    </view>
  </view>
</template>

2.js部分代码


	export default {
		props: {
			x: {
				type: Number,
				default: 80
			},
			y: {
				type: Number,
				default: 72
			},
			image: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				start: [0, 0],
				moveY: 0,
				moveX: 0,
				windowWidth: '',
				windowHeight: '',
			}
		},
		onShow() {
			const {
				windowWidth,
				windowHeight
			} = uni.getSystemInfoSync();
			this.windowWidth = windowWidth
			this.windowHeight = windowHeight
		},
		methods: {
			drag_start(event) {
				this.start[0] = event.touches[0].clientX - event.target.offsetLeft;
				this.start[1] = event.touches[0].clientY - event.target.offsetTop;
			},
			//判断防止悬浮球被拖出页面
			drag_hmove(event) {
				let tag = event.touches;
				if (tag[0].clientX < 0) {
					tag[0].clientX = 0
				}
				if (tag[0].clientY < 0) {
					tag[0].clientY = 0
				}
				if (tag[0].clientX > this.windowWidth) {
					tag[0].clientX = this.windowWidth
				}
				if (tag[0].clientY > this.windowHeight) {
					tag[0].clientY = this.windowHeight
				}
				this.moveX = tag[0].clientX - this.start[0];
				this.moveY = tag[0].clientY - this.start[1];
			},
		}
	}

3.css部分代码

.addNumberBox {
		width: 100%;
		height: 100%;
	}

	.addNumber {
		background: #FFFFFF;
		box-shadow: 0px 3px 7px 0px rgba(0, 0, 0, 0.35);
		border-radius: 50%;
		color: #26A2FF;
		position: fixed !important;
		width: 120rpx;
		height: 120rpx;
		text-align: center;
		z-index: 999 !important;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}