微信小程序实现手指缩放移动图片

微信小程序实现手指缩放移动图片

实现方式一: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');
  }
})
原文地址:https://www.cnblogs.com/cnsyear/p/12732106.html