微信小程序图片相对背景图移动和缩放

由于项目需要用到图片的缩放和移动,参考http://www.wxapp-union.com/portal.php?mod=view&aid=4083,做了个demo,并实现了想要的功能。

效果图如下:


测试.gif

js代码:

 Page({

 data: {
   // 大图(背景底图)变量
   backImgWidth: 0, //背景图宽(以屏幕宽)
   backImgHeight: 0, //背景图宽
   backImglevel: 0,


   // 小图(可移动、放大变量)
   handleImgWidth: 0,
   handleImgHeight: 0,
   // 移动
   handleImgTop: 0,
   handleImgleft: 0,

   // 缩放
   olddistance: 0,
   scale: 1,
   baseHeight: 0, //小图最小高度
   baseWidth: 0, //小图最小宽度

   previousTwoFinger: false, //此变量防止双指离开时,后离开的手指会触发图片移动
 },
 onLoad: function (options) {
   // 图片比例暂定为 2880 / 2160;
   // 并初始化大图宽高
   var ScreenWidth = wx.getSystemInfoSync().windowWidth;
   var level = 4 / 3;  
   var backImgHeight = ScreenWidth / level;

   // 初始化小图宽高,
   var hanImgWid = 100;  
   var levelHandle =  9 / 10;  
   var hanImgHei = hanImgWid / levelHandle;

   //  先让小图相对于大图定位(绝对定位)
   //  人像图片相对于背景图的到顶部距离
   var top = backImgHeight - hanImgHei;
   //  人像图片相对于背景图到左边部距离, 居中位置
   var left = (ScreenWidth - hanImgWid) / 2;

   this.setData({
     backImgWidth: ScreenWidth,
     backImgHeight: backImgHeight,
     backImglevel: level,

     handleImgWidth: hanImgWid,
     handleImgHeight: hanImgHei,

     handleImgTop: top,
     handleImgleft: left,

     baseHeight: hanImgHei,
     baseWidth: hanImgWid,
     handleImgWidth: hanImgWid,
     handleImgHeight: hanImgHei,
   })
 },
 getHandlImgStart: function (res) {
   // console.log("触摸开始", res);
   // 触摸开始时记录初始值(为计算缩放做准备)
   if(res.touches.length == 2){
     var distance = this.getDistance(res.touches[0], res.touches[1]);
     this.setData({
       olddistance: distance
     })
   }
 },
 getHandlImgEnd: function (res) {
   // console.log("触摸结束", res);
   this.setData({
     previousTwoFinger: false,
   })
 },
 getHandlImgMove: function (res) {
   // console.log("移动事件", res);
   if (res.touches.length == 1) {
     // 一只手指触摸触发移动
     if (!this.data.previousTwoFinger){
       this.handlImgMove(res.touches[0]);
     }
   } else if (res.touches.length == 2) {
     // 两只手指触发缩放
     this.handlImgZoom(res.touches[0], res.touches[1]);
   }
 },
 handlImgMove: function(obj){
   var limit_height = this.data.backImgHeight;
   var limit_width = this.data.backImgWidth;
   var imgWidth = this.data.handleImgWidth;
   var imgHeight = this.data.handleImgHeight;

   var imgTop = limit_height - imgHeight;
   var imgLeft = limit_width - imgWidth;

   var moveX = obj.pageX - imgWidth / 2;
   var moveY = obj.pageY - imgHeight / 2;
   // X轴移动距离
   if(moveX <= 0){
     moveX = 0;
   } else if(moveX >= imgLeft){
     moveX = imgLeft
   }
   if (moveY <= 0) {
     moveY = 0;
   } else if (moveY >= imgTop) {
     moveY = imgTop
   }
   // console.log("left: , top: ", moveX, moveY);
   this.setData({
     handleImgleft: moveX,
     handleImgTop: moveY,
   })
 },
 handlImgZoom: function(obj_1, obj_2){
   var that = this;
   // 小图最大最小缩放范围
   var maxHeight = this.data.backImgHeight;
   var maxWidth = this.data.backImgWidth;
   var minHeight = this.data.baseHeight;
   var minWidth = this.data.baseWidth;

   // 动态实际宽高
   var infactHeight = this.data.handleImgHeight;
   var infactWidth = this.data.handleImgWidth;
   var infactTop = this.data.handleImgTop;
   var infactLeft = this.data.handleImgleft;

   var oldDistance = this.data.olddistance;
   var distance = this.getDistance(obj_1, obj_2);
   var scale = distance / oldDistance;
   // console.log("初始距离,移动后距离", oldDistance,distance);
   // console.log("放大或缩小比例", scale);


   var top; var left
   top = infactTop - infactHeight * (scale - 1) / 2;
   left = infactLeft - infactWidth * (scale - 1) / 2;
   if (scale > 1) {
     // 放大
     top = infactTop - infactHeight * (scale - 1);
     left = infactLeft - infactWidth * (scale - 1);
     if (top < 0) {
       top = 0;
     }
     if (left < 0) {
       left = 0;
     }
   } else if (scale < 1 && scale > 0) {
     // 缩小
     top = infactTop + infactHeight * (1 - scale) / 2;
     left = infactLeft + infactWidth * (1 - scale) / 2;
     if (top > (maxHeight - minHeight)) {
       return;
     }
     if (left > (maxWidth - minWidth)) {
       return;
     }
   } else {
     // 比例不变时退出函数
     return;
   }
   var heigh = infactHeight * scale;
   var width = infactWidth * scale;
   // console.log("小图宽高:", heigh, width);
   if (heigh > maxHeight || heigh < minHeight || width > maxWidth || width < minWidth){
     return;
   }
   //console.log("top, left", top, left)
   this.setData({
     olddistance: distance,
     handleImgHeight: heigh,
     handleImgWidth: width,
     handleImgleft: left,
     handleImgTop: top,
     previousTwoFinger: true,
   })
 },
 getDistance: function (obj_1, obj_2){
   var distance = 0;
   var x1 = obj_1.pageX;
   var y1 = obj_1.pageY;
   var x2 = obj_2.pageX;
   var y2 = obj_2.pageY;
   xMove = x2 - x1;
   yMove = y2 - y1;
   distance = Math.sqrt(xMove*xMove + yMove*yMove);
   return distance;
 },
})

wxml

<view class="page">
  <image class="background_Img" 
    src="../../images/backImg.jpg" 
    style="width: {{backImgWidth}}px; height: {{backImgHeight}}px;"
    mode="aspectFit"
  ></image>

  <image 
    class="opreatImg" 
    src="../../images/moveImg.jpg" 
    style=" width: {{handleImgWidth}}px; height: {{handleImgHeight}}px; top: {{handleImgTop}}px; left: {{handleImgleft}}px;"
    bindtouchmove="getHandlImgMove"
    bindtouchstart="getHandlImgStart"
    bindtouchend="getHandlImgEnd" 
    mode="aspectFit"     
    ></image> 
</view>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • https://www.cnblogs.com/shenzikun1314/p/7805168.html 微信小程...
    无痕Q阅读 12,476评论 0 20
  • 原来爱是会让人失聪失语。 我听不到海风撩拨热带的椰树,听不到海浪涌吻湿热的沙滩,甚至听不到人流涌动中的声浪,只看到...
    俊成桶子阅读 651评论 24 0
  • 怀孕,生产,带娃⋯⋯很忙碌。所以暂不更新,谢谢支持的亲。当然,有一天我还会回来的。请继续关注巜中产中年》。
    湘君张阅读 887评论 4 14