移动端悬浮按钮+可随意拖动+松手后自动吸附到屏幕最近边。用fixed定位监听手指事件实现。很简单的小玩意儿,个人喜欢此类用户交互效果,特记录收纳下。可直接划走。
<template>
<view class="suspension" :style="{'top':fixedTop + 'rpx','left':fixedLeft + 'rpx','transition':fixedTrans+'s'}" @touchmove.stop.prevent="handleFixedMove" @touchend="handleFixeEnd" @click="suspensionClick">
<slot></slot>
</view>
</template>
1.确定按钮尺寸后(160rpx)计算最大水平/垂直定位距离。
- 计算屏幕 px 与 rpx 转化率,取rpx适配。
- 获取屏幕实际可用宽度后计算按钮最大水平/垂直定位距离。
- 设置默认水平/垂直定位距离。
created(){
this.rate = uni.getSystemInfoSync().windowWidth / 750;
this.maxFixedTop = uni.getSystemInfoSync().windowHeight / this.rate - 160;
this.maxFixedLeft = uni.getSystemInfoSync().windowWidth / this.rate - 160;
this.fixedTop = this.maxFixedTop - 200;
this.fixedLeft = this.maxFixedLeft;
}
2.监听手指移动。
- 手指移动实时更新水平/垂直定位距离。
handleFixedMove(e){
this.fixedTrans = 0;
let spaceY = e.touches[0].clientY / this.rate;
let spaceX = e.touches[0].clientX / this.rate;
if(spaceX < 80){
this.fixedLeft = 0;
}else if(spaceX > this.maxFixedLeft + 80){
this.fixedLeft = this.maxFixedLeft;
}else{
this.fixedLeft = spaceX - 80;
}
if(spaceY < 80){
this.fixedTop = 0;
}else if(spaceY > this.maxFixedTop + 80){
this.fixedTop = this.maxFixedTop;
}else{
this.fixedTop = spaceY - 80;
}
}
3.监听手指离开屏幕。
- 手指离开屏幕判断当前定位距离屏幕边缘最近方向。
- 取最近方向定位为0,transition 给适当过渡时间。
handleFixeEnd(e){
this.fixedTrans = 0.3;
let top = e.changedTouches[0].clientY / this.rate;
let left = e.changedTouches[0].clientX / this.rate;
let bottom = this.maxFixedTop + 160 - top;
let right = this.maxFixedLeft + 160 - left;
let min = [top,left,bottom,right].sort((a,b) => a - b)[0];
if(min == top){
this.fixedTop = 0
}else if(min == bottom){
this.fixedTop = this.maxFixedTop
}else if(min == left){
this.fixedLeft = 0
}else{
this.fixedLeft = this.maxFixedLeft
}
}