只做了放大预览和拖拽,拖拽没有做边界判断,代码可以直接拿去用。
用了其他插件放大都会出现失真的问题,于是直接手写了个半成品,优化没有做。
<template>
<view class="notFound" style="position: relative;">
<view class="notFoundBox">
<view class="img">
<img
src="/prod/default/20230107/XEHz9bZVE3SJbTgthy.jpg"
@click="isshow = true"
style="width: 100%"
/>
</view>
</view>
<view
style="
height: 100%;
width: 100%;
position: absolute;
left:0;
top:0;
background: rgba(0, 0, 0, 0.8);
overflow:hidden;
"
v-show="isshow"
@click.stop="closeImg"
@touchstart="gtouchstart"
@touchmove="gtouchmove"
@touchend="gtouchend"
>
<view class="img" style="margin-top: 50%;position: relative;"
>
<img
class="setImg"
style="position: absolute; width:52vh;"
:src="imgPath"
:style="{ left: L + 'px', top: T + 'px' ,}"
/>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
//图片单指拖动
L:0,
T:0,
//边界判断
windowW:0,
windowH:0,
//双指判断放大缩小
start: {
pageX: null,
pageY: null,
},
//双指首次操作未结束并连续进行放大缩小操作
start2: {
pageX: null,
pageY: null,
},
//
distance:null,
//放大倍数
swipeScale:1,
//双指操作是否结束
once:false,
//打卡图片预览
isshow: false,
imgPath: "/prod/default/20230107/XEHz9bZVE3SJbTgthy.jpg",
};
},
onLoad(){
let that = this
uni.getSystemInfo({//可以用来做边界判断
success: function(res){
console.log(res)
that.windowW = res.windowWidth
that.windowH = res.windowHeight
}
})
},
mounted(){
//获取dom元素用于后期操作
this.img = document.getElementsByClassName('setImg')[0]
},
methods: {
gtouchstart(e) {
if(e.touches.length>1){//双手势
let point1 = e.touches[0];
let point2 = e.touches[1];
let deltaX = Math.abs(point2.pageX - point1.pageX);
let deltaY = Math.abs(point2.pageY - point1.pageY);
this.distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);//初始时候的距离,r1
}else{
//单手势事件
this.start.pageX = e.touches[0].pageX;
this.start.pageY = e.touches[0].pageY;
this.start2.pageX = e.touches[0].pageX;
this.start2.pageY = e.touches[0].pageY;
}
},
gtouchmove(e) {
if(e.touches.length>1){
let point1 = e.touches[0];
let point2 = e.touches[1];
let deltaX = Math.abs(point2.pageX - point1.pageX);
let deltaY = Math.abs(point2.pageY - point1.pageY);
let distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);//1
if(this.distance){
let size = distance/this.distance;
// size大于1 放大手势
// size小于1 缩小手势
if(size > 1){
this.swipeScale += 0.05
}else{
//swipeScale 小于等于1 设置minSize(最小缩放值)
if(this.swipeScale <= 1 ){
this.swipeScale = 1
this.L = 0
this.T = 0
}else{
this.swipeScale -= 0.05
}
}
//执行缩放事件
this.img.style.transform = "scale("+this.swipeScale +")";
}
}else{
//单手势事件
let deltaX = e.touches[0].pageX - this.start.pageX;
let deltaY = e.touches[0].pageY- this.start.pageY;
if(this.once){//判断是否连续放大缩小
if(deltaX<0 && deltaX>this.start2.pageX){
this.L += (1.5*this.swipeScale)
}else if(deltaX > 0 && deltaX>this.start2.pageX){//2 3
this.L += (1.5*this.swipeScale)
}
if(deltaX<0 && deltaX<this.start2.pageX){
this.L -= (1.5*this.swipeScale)
}else if(deltaX > 0 && deltaX<this.start2.pageX){//2 3
this.L -= (1.5*this.swipeScale)
}
if(deltaY<0 && deltaY>this.start2.pageY){
this.T += (1.5*this.swipeScale)
}else if(deltaY > 0 && deltaY>this.start2.pageY){//2 3
this.T += (1.5*this.swipeScale)
}
if(deltaY<0 && deltaY<this.start2.pageY){
this.T -= (1.5*this.swipeScale)
}else if(deltaY > 0 && deltaY<this.start2.pageY){//2 3
this.T -= (1.5*this.swipeScale)
}
}else{
this.once = true
if(deltaX >0){
this.L += (1.5*this.swipeScale)
}else if(deltaX < 0){
this.L -= (1.5*this.swipeScale)
}
if(deltaY >0){
this.T += (1.5*this.swipeScale)
}else if(deltaY < 0){
this.T -= (1.5*this.swipeScale)
}
}
//存储n-1的位置,用于判断连续放大缩小操作
this.start2.pageX = deltaX;
this.start2.pageY = deltaY;
}
},
gtouchend(e) {
//手势结束清除无用值
this.once = false
this.start = {
pageX: null,
pageY: null,
};
this.start2 = {
pageX: null,
pageY: null,
};
},
preImg() {
this.isshow = true;
},
closeImg(){
//关闭预览img重置判断值
this.swipeScale = 1
this.img.style.transform = "scale("+this.swipeScale +")";
this.isshow = false;
this.L = 0
this.T = 0
}
},
};
</script>
<style lang="scss" scoped>
.notFound {
position: relative;
height: 100vh;
background: white;
.notFoundBox {
position: absolute;
top: 30%;
width: 100%;
text-align: center;
.img {
width: 100%;
}
.title {
font-weight: bold;
font-size: 36rpx;
color: #666666;
margin: 48rpx 0;
view {
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 500;
color: #999999;
}
}
.back {
width: 250rpx;
height: 72rpx;
color: white;
text-align: center;
border-radius: 72rpx;
background-color: #286043;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
}
}
</style>