实现悬浮按钮拖动,兼容h5和微信小程序
h5用js写,微信小程序用
代码里面没有完全实现吸附边缘的功能,需要吸附边缘的话还得自己再完善下(h5的吸附边缘是可以的,小程序的还有点问题)
主要功能是:图片上写文字的悬浮按钮,文字使用的是::after实现的,图片就用的u-image标签
(图片和文字,用背景图好像更方便诶,文字就用绝对定位、flex或者是margin)
<template>
<!-- #ifndef MP-WEIXIN -->
<view class="btn" :style="{ left: left + 'px', top: top + 'px' }" @touchstart="handleTouchStart"
@touchmove.prevent="handleTouchMove" @touchend="handleTouchEnd" @click="clickHandle">
<u--image src="放自己的图" width="144rpx"
height="128rpx" class="link"></u--image>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<movable-area class="drag-area" style="height:100vh">
<movable-view direction="all" :x="x" :y="y" :damping="40" @touchend="handleTouchEnd" class="btn"
@click="clickHandle" :animation="false">
<u--image src="放自己的图"
width="144rpx" height="128rpx"></u--image>
</movable-view>
</movable-area>
<!-- #endif -->
</template>
left: 0, // 按钮左侧位置
top: 0, // 按钮顶部位置
startX: 0, // 触摸起始X坐标
startY: 0,
screenWidth: 0, // 屏幕宽度
screenHeight: 0, // 屏幕高度
x: 0, // X轴位置
y: 500, // Y轴位置
systemInfo: {}, // 系统信息
btnWidth: 72, // 按钮宽度(px)
btnHeight: 64, // 按钮高度(px)
mounted() {
const systemInfo = uni.getSystemInfoSync();
this.screenWidth = systemInfo.windowWidth;
this.screenHeight = systemInfo.windowHeight;
this.left = this.screenWidth - this.btnWidth - 10;
this.top = 500;
this.x = this.screenWidth - this.btnWidth - 10;
this.y = 500;
},
handleTouchStart(e) {
// 记录触摸起点
this.startX = e.touches[0].clientX;
this.startY = e.touches[0].clientY;
},
handleTouchMove(e) {
if (e.cancelable) e.preventDefault();
const deltaX = e.touches[0].clientX - this.startX;
const deltaY = e.touches[0].clientY - this.startY;
let newLeft = this.left + deltaX;
let newTop = this.top + deltaY;
newLeft = Math.max(0, Math.min(newLeft, this.screenWidth - this.btnWidth));
newTop = Math.max(0, Math.min(newTop, this.screenHeight - this.btnHeight));
this.left = newLeft;
this.top = newTop;
this.startX = e.touches[0].clientX;
this.startY = e.touches[0].clientY;
},
handleTouchEnd() {
// this.autoAttachToEdge();
},
// 拖动过程中触发
onDragChange(e) {
// 实时更新位置
// this.x = e.detail.x
// this.y = e.detail.y
},
autoAttachToEdge() {
// 吸附到左侧或右侧
const midScreen = this.screenWidth / 2;
if (this.left < midScreen) {
this.left = 10; // 吸附到左边
} else {
this.left = this.screenWidth - this.btnWidth - 10; // 吸附到右边
}
},
// 点击按钮的逻辑
clickHandle(){}
.btn {
position: fixed;
z-index: 999;
}
/* #ifndef MP-WEIXIN */
.link {
&::after {
content: 'XXX';
font-size: 24px;
color: #fff;
position: absolute;
bottom: 4px;
left: 0;
line-height: 34px;
width: 100%;
text-align: center;
z-index: 999;
}
}
/* #endif */
/* #ifdef MP-WEIXIN */
.btn ::v-deep .u-image::after {
content: 'XXX';
font-size: 24px;
color: #fff;
position: absolute;
bottom: 4px;
left: 0;
line-height: 34px;
width: 100%;
text-align: center;
z-index: 999;
}
/* #endif */
/* 拖拽区域必须设置尺寸 */
.drag-area {
width: 100%;
position: fixed;
pointer-events: none;
/* 防止遮挡下方内容 */
z-index: 999;
}
/* 可拖拽按钮样式 */
.btn {
width: 144rpx;
height: 128rpx;
pointer-events: auto;
/* 允许交互 */
}
/* 隐藏movable-view默认边框 */
movable-view::before {
display: none;
}