微信小程序实现手指缩放移动图片
实现方式一:view子元素缩放、移动
通过监听父view的touch事件,单指touch move用于移动,双指touch move则用于缩放,通过transform:translate进行移动、transform:scale进行缩放。
- wxml:
<!--scale.wxml-->
<view class="container">
<view class="tip">
<text>view子元素缩放、移动 </text>
<text>说明:双指缩放开发工具上并不支持,需要在真机上进行。 </text>
</view>
<view class="img" catchtouchstart="touchstartCallback" catchtouchmove="touchmoveCallback" catchtouchend="touchendCallback" >
<image style="transform:translate({{stv.offsetX}}px, {{stv.offsetY}}px) scale({{stv.scale}});" src="../../images/timg.jpeg"></image>
</view>
<view>
<text>x: {{stv.offsetX}}</text>,
<text>y: {{stv.offsetY}}</text>,
<text>d: {{stv.distance}}</text>,
<text>s: {{stv.scale}}</text>,
</view>
</view>
- wxss:
/**scale.wxss**/
.img {
100%;
height: 500rpx;
overflow: hidden;
background: #AAA;
}
.img image {
height:400px;
}
- js:
//scale.js
//获取应用实例
var app = getApp()
Page({
data: {
stv: {
offsetX: 0,
offsetY: 0,
zoom: false, //是否缩放状态
distance: 0, //两指距离
scale: 1, //缩放倍数
}
},
//事件处理函数
touchstartCallback: function(e) {
//触摸开始
console.log('touchstartCallback');
console.log(e);
if (e.touches.length === 1) {
let {clientX, clientY} = e.touches[0];
this.startX = clientX;
this.startY = clientY;
this.touchStartEvent = e.touches;
} else {
let xMove = e.touches[1].clientX - e.touches[0].clientX;
let yMove = e.touches[1].clientY - e.touches[0].clientY;
let distance = Math.sqrt(xMove * xMove + yMove * yMove);
this.setData({
'stv.distance': distance,
'stv.zoom': true, //缩放状态
})
}
},
touchmoveCallback: function(e) {
//触摸移动中
//console.log('touchmoveCallback');
//console.log(e);
if (e.touches.length === 1) {
//单指移动
if (this.data.stv.zoom) {
//缩放状态,不处理单指
return ;
}
let {clientX, clientY} = e.touches[0];
let offsetX = clientX - this.startX;
let offsetY = clientY- this.startY;
this.startX = clientX;
this.startY = clientY;
let {stv} = this.data;
stv.offsetX += offsetX;
stv.offsetY += offsetY;
stv.offsetLeftX = -stv.offsetX;
stv.offsetLeftY = -stv.offsetLeftY;
this.setData({
stv: stv
});
} else {
//双指缩放
let xMove = e.touches[1].clientX - e.touches[0].clientX;
let yMove = e.touches[1].clientY - e.touches[0].clientY;
let distance = Math.sqrt(xMove * xMove + yMove * yMove);
let distanceDiff = distance - this.data.stv.distance;
let newScale = this.data.stv.scale + 0.005 * distanceDiff;
this.setData({
'stv.distance': distance,
'stv.scale': newScale,
})
}
},
touchendCallback: function(e) {
//触摸结束
console.log('touchendCallback');
console.log(e);
if (e.touches.length === 0) {
this.setData({
'stv.zoom': false, //重置缩放状态
})
}
},
onLoad: function () {
console.log('onLoad');
}
})
实现方式二:scroll-view子元素缩放
通过监听父scroll-view的touch事件,计算出两指的距离,缩放用的是css zoom来进行的,因为transform:scale的缩放不能改变box的大小,对于scroll-view来说就会产生问题。但是用zoom有一个问题就是缩放基点是按左上角进行的, 体验不是很好。
- wxml:
<!--scale.wxml-->
<view class="container">
<view class="tip">
<text>scroll-view子元素缩放</text>
<text>说明:双指缩放开发工具上并不支持,需要在真机上进行。 </text>
</view>
<scroll-view class="img" bindtouchstart="touchstartCallback" bindtouchmove="touchmoveCallback" bindtouchend="touchendCallback" scroll-x="true" scroll-y="true" >
<image style="zoom:{{stv.scale}};" src="../../images/timg.jpeg"></image>
</scroll-view>
<view>
<text>x: {{stv.offsetX}}</text>,
<text>y: {{stv.offsetY}}</text>,
<text>d: {{stv.distance}}</text>,
<text>s: {{stv.scale}}</text>,
</view>
</view>
- wxss:
/**scale.wxss**/
.img {
100%;
height: 500rpx;
background: #AAA;
text-align: center;
}
.img image {
height: 800rpx;
600rpx;
}
- js:
//scale.js
//获取应用实例
var app = getApp()
Page({
data: {
stv: {
offsetX: 0,
offsetY: 0,
zoom: false, //是否缩放状态
distance: 0, //两指距离
scale: 1, //缩放倍数
}
},
//事件处理函数
touchstartCallback: function(e) {
//触摸开始
console.log('touchstartCallback');
console.log(e);
if (e.touches.length === 1) {
let {clientX, clientY} = e.touches[0];
this.startX = clientX;
this.startY = clientY;
this.touchStartEvent = e.touches;
} else {
let xMove = e.touches[1].clientX - e.touches[0].clientX;
let yMove = e.touches[1].clientY - e.touches[0].clientY;
let distance = Math.sqrt(xMove * xMove + yMove * yMove);
this.setData({
'stv.distance': distance,
'stv.zoom': true, //缩放状态
})
}
},
touchmoveCallback: function(e) {
//触摸移动中
console.log('touchmoveCallback');
console.log(e);
if (e.touches.length === 1) {
//单指移动
if (this.data.stv.zoom) {
//缩放状态,不处理单指
return ;
}
let {clientX, clientY} = e.touches[0];
let offsetX = clientX - this.startX;
let offsetY = clientY- this.startY;
this.startX = clientX;
this.startY = clientY;
let {stv} = this.data;
stv.offsetX += offsetX;
stv.offsetY += offsetY;
stv.offsetLeftX = -stv.offsetX;
stv.offsetLeftY = -stv.offsetLeftY;
this.setData({
stv: stv
});
} else {
//双指缩放
let xMove = e.touches[1].clientX - e.touches[0].clientX;
let yMove = e.touches[1].clientY - e.touches[0].clientY;
let distance = Math.sqrt(xMove * xMove + yMove * yMove);
let distanceDiff = distance - this.data.stv.distance;
let newScale = this.data.stv.scale + 0.005 * distanceDiff;
this.setData({
'stv.distance': distance,
'stv.scale': newScale,
})
}
},
touchendCallback: function(e) {
//触摸结束
console.log('touchendCallback');
console.log(e);
if (e.touches.length === 0) {
this.setData({
'stv.zoom': false, //重置缩放状态
})
}
},
onLoad: function () {
console.log('onLoad');
}
})