效果
全部代码
<!--
minRight 与 minBottom 可传入,用来设置初始位置,组件内部使用了 百分比定位 ( 考虑到rem 与 px 转换 可能比较麻烦 )
暂时实现不是很完美 需要重新计算
目前只能初始设置在屏幕的右下部分, 其他部分会有问题
使用方式
<DragSide>
<img src="./assets/icon/consult.png">
</DragSide>
-->
<template>
<!-- @touchmove.prevent阻止浏览器滚动 -->
<div
ref="fixed_side"
class="fixed-side"
@touchmove.prevent="touchmove"
@touchend="touchend"
:style="{
bottom: offsetBottom + '%',
right: offsetRight + '%',
'transition-duration': transitionDuration,
}"
>
<slot></slot>
</div>
</template>
<script>
export default {
props: {
minRight: {
type: Number,
default: 5,
validator(value) {
return value > 0 && value < 30;
},
},
minBottom: {
type: Number,
default: 10,
},
},
data() {
return {
offsetRight: this.minRight,
offsetBottom: this.minBottom,
transitionDuration: "0s",
};
},
methods: {
// 获取dom相关属性(宽,高)
getRect() {
let fixedSide = this.$refs.fixed_side;
return fixedSide.getBoundingClientRect();
},
touchmove(e) {
let { width, height } = this.getRect();
let { pageX, pageY } = e.targetTouches[0];
this.offsetRight =
((window.innerWidth - pageX - width / 2) / window.innerWidth) * 100;
this.offsetBottom = ((window.innerHeight - pageY - height / 2) / window.innerHeight) * 100;
let RightB = 100 - this.minRight - (width / window.innerWidth) * 100;
// 下边设置上下左右四个边界, 不可移出屏幕
if (this.offsetRight < this.minRight) this.offsetRight = this.minRight;
if (this.offsetRight > RightB) this.offsetRight = RightB;
if (this.offsetBottom < 10) this.offsetBottom = 10;
if (this.offsetBottom > 90) this.offsetBottom = 90;
},
touchend(e) {
let { pageX } = e.changedTouches[0];
let innerWidth = window.innerWidth;
let { width } = this.getRect();
let RightB = 100 - this.minRight - (width / window.innerWidth) * 100;
// 通过 transitionDuration 设置松手后的动画效果
this.transitionDuration = "0.2s";
// 判断松手的时候手指位置处于屏幕哪一侧
if (pageX >= innerWidth / 2) this.offsetRight = this.minRight;
else this.offsetRight = RightB;
// 重新设置为0 是为了在拖动过程中不受影响
setTimeout(() => {
this.transitionDuration = "0s";
}, 30);
},
},
};
</script>
<style scoped lang="scss">
.fixed-side {
position: fixed;
z-index: 10;
}
</style>
总想为代码找个最优解,但是又找不到, 不说了,学习吧 !