uniapp封装movable-area+movable-view组件,实现悬浮按钮可拖动,自动吸附边缘效果,自动向两边靠拢
兼容H5、App、微信小程序
子组件
/components/ShopCar/ShopCar.vue
<template>
<view class="ShopCar">
<movable-area class="movableArea" v-if="isShow">
<movable-view class="movableView" :position="position" :x="x" :y="y" :direction="direction"
:damping="damping" @change="onChange" @touchend="onTouchend">
<view class="icon-box" @click="handleIcon()">
<u-icon name="arrow-upward" color="#ff6a00" size="20"></u-icon>
</view>
</movable-view>
</movable-area>
</view>
</template>
<script>
export default {
props: {
damping: {
type: Number,
default: 10
},
direction: {
type: String,
default: "all"
},
position: {
type: Number,
default: 4
},
},
data() {
return {
x: 0,
y: 0,
x1: 0,
x2: 0,
y1: 0,
y2: 0,
move: {
x: 0,
y: 0
},
isShow: false
}
},
mounted() {
uni.getSystemInfo({
success: (res) => {
this.x1 = 0;
this.x2 = parseInt(res.windowWidth) - 50;
this.y1 = 0;
this.y2 = parseInt(res.windowHeight) - 20;
this.$nextTick(() => {
if (this.position == 1 || this.position == 2) this.y = parseInt(this.y2 * 0.2);
if (this.position == 3 || this.position == 4) this.y = parseInt(this.y2 * 0.8);
if (this.position == 1 || this.position == 3) this.x = parseInt(this.x1);
if (this.position == 2 || this.position == 4) this.x = parseInt(this.x2);
this.move.x = this.x;
this.move.y = this.y;
this.isShow = true
})
}
})
},
methods: {
onChange(e) {
if (e.detail.source === "touch") {
this.move.x = e.detail.x;
this.move.y = e.detail.y;
}
},
onTouchend() {
this.x = this.move.x;
this.y = this.move.y;
this.$nextTick(() => {
if (this.move.x < this.x2 / 2) this.x = this.x1;
else this.x = this.x2;
})
},
handleIcon() {
uni.pageScrollTo({
scrollTop: 0,
duration: 0,
});
}
},
}
</script>
<style lang="scss" scoped>
.ShopCar {
.movableArea {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none; //设置area元素不可点击,则事件便会下移至页面下层元素
z-index: 999;
.movableView {
width: 70rpx;
height: 70rpx;
pointer-events: auto;
padding: 0 30rpx;
.icon-box {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border: 1rpx solid #ff6a00;
box-sizing: border-box;
border-radius: 50%;
background-color: #fff;
animation: iconBox 5s linear infinite; //进行旋转
}
@keyframes iconBox {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(90deg);
}
50% {
-webkit-transform: rotate(180deg);
}
75% {
-webkit-transform: rotate(270deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
}
}
}
</style>
父组件
<template>
<ShopCar v-if="scrollTop>200" />
</template>
<script>
export default {
data() {
return {
scrollTop: 0
}
},
onPageScroll(e) {
this.scrollTop = e.scrollTop
},
}
</script>