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

由于项目需要用到图片的缩放和移动,参考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>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

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