因为是手机端,所以需要触摸可移动,双指放大缩小。
首先在components里建个组件
查看图片使用 uni-popup 弹窗
要注意 transform的translate和scale属性在同一标签上不会一起生效
移动就根据触摸效果进行偏移图片
缩放就根据双指距离的变大变小进行缩放
<template>
<view>
<uni-popup style="z-index: 99998;" ref="showImage" type="center">
<view :style="{'transform':'translate('+x+'px,'+y+'px)'}">
<img
:style="{'transform':'scale(' + scale +')','height': height + 'px'}"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
@touchcancel="touchcancel"
mode="aspectFit"
:src="src"></img>
</view>
<view class="closePopup" @click="close">
<uni-icons type="closeempty" size="32" color="#fff"></uni-icons>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
name:"selectImage",
data() {
return {
height: 0,
src: '',
x: 0,
y:0,
clientX: 0,
clientY: 0,
moveX: 0,
moveY: 0,
touchType: 0, // 0为单指触摸 1为双指
// 初始双指距离
distance: 0,
// 初始缩放比例
scale: 1
};
},
created() {
const me = this
uni.getSystemInfo({
success(res) {
// 默认图片高度占屏幕一半展示
me.height = res.windowHeight / 2
}
})
},
methods: {
// 获取两点距离
getDistance (point1, point2) {
const x = point1.clientX - point2.clientX
const y = point1.clientY - point2.clientY
return Math.sqrt(x*x + y*y)
},
// 触摸开始
touchstart (e) {
// 当触摸事件为一个时
if (e.touches.length === 1) {
// 记录开始触摸位置
this.clientX = e.changedTouches[0].clientX
this.clientY = e.changedTouches[0].clientY
this.touchType = 0
} else if (e.touches.length === 2) {
// 双指进行放大缩小操作
this.touchType = 1
// 获取双指距离
this.distance = this.getDistance(e.touches[0], e.touches[1])
}
},
// 触摸移动中
touchmove (e) {
// 当触摸事件为一个时
if (this.touchType === 0) {
// 记录移动的距离
const moveX = e.changedTouches[0].clientX - this.clientX
const moveY = e.changedTouches[0].clientY - this.clientY
// 最终偏移距离为初始偏移距离+当前偏移距离
this.x = this.moveX + moveX
this.y = this.moveY + moveY
} else if (this.touchType === 1) {
// 双指进行放大缩小操作
if (e.touches.length === 2) {
// 获取移动后的双指距离
const le = this.getDistance(e.touches[0], e.touches[1])
// 最终放大 缩小效果为 初始放大缩小比例 * 当前放大缩小比例
const bl = le / this.distance
const scale = this.scale * bl
this.scale = scale > 0.1 ? scale : 0.1
// 随着移动将开始的位置重置 不然会一次性放很大 或者缩很小,不好控制
this.distance = le
}
}
},
// 触摸结束
touchend (e) {
// 当触摸事件为一个时
if (this.touchType === 0) {
// 记录最终移动距离
const moveX = e.changedTouches[0].clientX - this.clientX
const moveY = e.changedTouches[0].clientY - this.clientY
// 最终偏移距离为初始偏移距离+当前偏移距离
this.x = this.moveX + moveX
this.y = this.moveY + moveY
// 当前偏移距离设置为当前位置
this.moveX = this.x
this.moveY = this.y
} else if (this.touchType === 1) {
// 当双指松开后
console.log(e)
}
},
// 因电话等打断时触发
touchcancel (e) {
if (this.touchType === 0) {
this.x = 0
this.y = 0
} else {
this.clientX = 0
this.clientY = 0
this.moveX = 0
this.moveY = 0
this.touchType = 0 // 0为单指触摸 1为双指
// 初始双指距离
this.distance = 0
// 初始缩放比例
this.scale = 1
}
},
open () {
this.$refs.showImage.open()
},
close () {
this.x = 0
this.src = ''
this.y = 0
this.clientX = 0
this.clientY = 0
this.moveX = 0
this.moveY = 0
this.touchType = 0 // 0为单指触摸 1为双指
// 初始双指距离
this.distance = 0
// 初始缩放比例
this.scale = 1
this.$refs.showImage.close()
}
}
}
</script>
<style>
.closePopup {
position: fixed;
top: 40px;
right: 40px;
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
z-index: 99999;
}
</style>
外面组件调用时引用或者全局注册后使用
外面图片上加个点击事件
@click="look(url)"
方法直接调用组件open方法就OK了。
look (url) {
this.$refs.showImg.src = url
this.$refs.showImg.open()
},
效果图:
---------------查看-------------------------------移动------------------------------缩放