子组件
<template>
<div style="padding: 6px 7px">
<div class="box" :style="getStyle(1)">
<img :style="getStyle(1)" :src="`data:image/jpeg;base64,${data.image}`" alt="">
<div class="slids" :style="{'left': elePos.x + 'px', 'top': elePos.y + 'px', ...getStyle(3) }">
<img style="width: 100%; height: 100%" :src="`data:image/jpeg;base64,${data.slide}`" alt="">
</div>
</div>
<div class="slidBox" :style="getStyle(2)">
<div class="slidBoxItem"></div>
<img class="slid" :style="{width: '52px', height: '52px', margin: '1px 0 0 0','left': elePos.x + 'px', 'top': elePos.y + 'px' }"
src="@/assets/images/saleAndPurchase/handler_bg.png" alt=""
@mousedown.self="dragStartHandler"
@touchstart.stop="dragStartHandler"
@mousemove="draggingHandler"
@touchmove.stop="draggingHandler"
@mouseup="dragEndHandler"
@touchend.stop="dragEndHandler"
>
<!-- <div class="slid" :style="{'left': elePos.x + 'px', 'top': elePos.y + 'px' }"
@mousedown.self="dragStartHandler"
@touchstart.stop="dragStartHandler"
@mousemove="draggingHandler"
@touchmove.stop="draggingHandler"
@mouseup="dragEndHandler"
@touchend.stop="dragEndHandler">
</div> -->
</div>
<div class="repossessColse">
<img @click.stop="close" style="width: 24px; height: 24px; margin: 0 16px" src="@/assets/images/saleAndPurchase/closes.png" alt="">
<img @click.stop="repossess" style="width: 24px; height: 24px" src="@/assets/images/saleAndPurchase/repossess.png" alt="">
</div>
</div>
</template>
<script>
/**
* 必传参数 data
* data={ width:number,height:number,randomStr:string,pos:{height:number},slideWidth:number,slideHeight:number,image:string}
* ******************************
* 回调方法 callBack(type,distance)
* type: 按下滑块|拖动滑块|松开滑块
* distance: 滑块已滑动的距离
*/
export default {
props:['data'],
components: {},
data() {
return {
fatherbox: null,
innerbox: null,
slidsbox: null,
width: 300,
height: 186,
// width: 300,
// height: 186,
// randomStr: '"123540010cdf4d6eb3ce86eee1894d92"',
// pos:{
// height: 42
// width: 108
// },
// slideWidth:83,
// slideHeight: 37,
// 元素位置,用于样式绑定,动态更新位置(:style="{left: `${x}px`, top: `${y}px`}")
elePos: {
x: null,
y: null
},
// 手指(鼠标)触摸点[即拖拽开始的位置]距离拖拽元素左上角的距离
diffOfTarget: {
x: 0,
y: 0
}
};
},
created() {
console.log(this.data);
},
mounted() {
this.$nextTick(() => {
this.fatherbox = document.querySelector('.van-popup');
this.innerbox = document.querySelector('.slid');
this.slidsbox = document.querySelector('.slids');
});
},
methods: {
getStyle(e){
if(e == 1){
return {
width: this.data.width+'px',
height: this.data.height+'px',
}
}else if(e == 2){
return {
width: this.data.width+'px',
}
}else if(e == 3){
return {
width: this.data.slideWidth+'px',
height: this.data.slideHeight+'px',
top: this.data.pos.height + 6 + 'px',
}
}
},
dragStartHandler (e) {
let touch = e
if (e.touches) {
touch = e.touches[0]
}
this.diffOfTarget.x = touch.clientX - e.target.offsetLeft
this.diffOfTarget.y = touch.clientY - e.target.offsetTop
// 解决滑动穿透问题
let scrollTop = document.scrollingElement.scrollTop
// console.log(scrollTop)
// todo 在项目的全局样式下,需要定义一个modal-open的样式类
/**
* body.modal-open {
* position: fixed;
* width: 100%;
* min-height: 100%;
* }
*/
document.body.classList.add('modal-open')
document.body.style.top = -scrollTop + 'px'
// console.log(this.diffOfTarget.y);
let dragEndHandlerLeft = this.innerbox.offsetLeft-7
this.$emit('callBack','dragStartHandler',dragEndHandlerLeft)
},
draggingHandler (e) {
let touch = e
if (e.touches) {
touch = e.touches[0]
}
// 设置拖拽元素的位置
this.elePos.x = touch.clientX - this.diffOfTarget.x // 左右拖拽
// this.elePos.y = touch.clientY - this.diffOfTarget.y // 上下拖拽(不需要)
// let limitWidth = this.data.width-e.target.clientWidth-1 || 244 || window.screen.width
/**
* 限制元素不能超过滑道
* this.slidsbox.offsetWidth | 图片缺块宽度
* e.target.clientWidth | 滑块宽度
*/
let limitWidth = this.fatherbox.offsetWidth - this.slidsbox.offsetWidth - 7 // 滑动距离-滑块宽度-父元素padding |
let limitHeight = window.screen.height
if (this.elePos.x < 7) {
this.elePos.x = 7
} else if (this.elePos.x > limitWidth) {
this.elePos.x = limitWidth
}
if (this.elePos.y < 0) {
this.elePos.y = 0
} else if (this.elePos.y > limitHeight) {
this.elePos.y = limitHeight - e.target.clientHeight
}
// console.log('limitWidth',limitWidth,'this.elePos.x =',this.elePos.x );
// console.log('滑动距离',this.innerbox.offsetLeft);
// console.log('滑块宽度',this.innerbox.offsetWidth);
// console.log('父元素距离',this.fatherbox.offsetLeft);
// console.log('父元素宽度',this.fatherbox.offsetWidth);
let dragEndHandlerLeft = this.innerbox.offsetLeft-7
this.$emit('callBack','draggingHandler',dragEndHandlerLeft)
},
dragEndHandler (e) {
// console.log('松开距离',this.innerbox.offsetLeft-7);
let dragEndHandlerLeft = this.innerbox.offsetLeft-7
document.body.classList.remove('modal-open')
this.$emit('callBack','dragEndHandler',dragEndHandlerLeft)
},
repossess() { // 刷新
this.elePos.x = null
this.diffOfTarget.x = 0
// this.innerbox.offsetLeft = 0
let scrollTop = document.scrollingElement.scrollTop
console.log('scrollTop',scrollTop);
document.body.classList.add('modal-open')
document.body.style.top = -scrollTop + 'px'
// this.innerbox.offsetLeft = 7
document.body.classList.remove('modal-open')
this.$emit('repossess')
},
close() {
this.$emit('close')
}
},
};
</script>
<style lang="scss" scoped>
.box {
width: 350px;
height: 100px;
overflow: hidden;
}
.repossessColse {
height: 40px;
display: flex;
justify-content: flex-end;
flex-direction: row;
align-items:flex-end;
}
.slidBox {
width: 100%;
height: 52px;
overflow: none;
margin: auto;
display: flex;
align-items: center;
justify-content: flex-end;
.slidBoxItem {
width: 98%;
height: 37px;
background-color: #E6E6E6;
border-radius: 50px;
}
&::-webkit-scrollbar {
width: 0px; /*对垂直流动条有效*/
height: 0px; /*对水平流动条有效*/
// background-color: red;
}
.slid {
width: 52px;
height: 52px;
}
}
.slid {
position: fixed;
left: 7px;
bottom: 46px;
// width: 36px;
// height: 36px;
cursor: pointer;
}
.slids {
position: fixed;
left: 7px;
top: 0px;
width: 50px;
height: 50px;
cursor: pointer;
// background-color: yellow;
}
</style>
父组件
<slide-verification-puzzle
v-if="show"
@callBack="callBack"
@close="show = false"
@repossess="repossess()"
ref="slider"
:data="encodedImage"
></slide-verification-puzzle>