在移动设备上放大图片查看图片细节的俩种方法

  类似淘宝京东上的产品图,我们可以放大来看产品的具体细节。那么,在移动设备上,基于Web浏览器的这种效果又是如何实现的呢?

一.使用touchEvent来实现,关于touchEvent的一些基本知识,可以阅读文章——多点触摸网络开发

1.页面代码

<div id="warpper" class="warpper">
<div class="clearfix"></div>
    <div id="content" class="content" onclick="change()" >
        <img id="testimg" class="testimg" src="http://image.zcool.com.cn/img2/21/50/m_1312514725921.jpg">
    </div>
</div>

2.CSS代码

 html, body{
    margin: 0;
    padding: 0;
    width:100%;
    height:100%;
    background:#ddd;
  }

 .warpper{
    position:relative;
    width:100%;
    height:100%;
    margin:auto;

 }
 .clearfix{
    position:relative;
    width:100%;
    height:100px;
 }
  .content{
    position:relative;
    width:450px;
    height:338px;
    margin:auto;
    border:2px solid  #92B2CA;
    overflow:hidden ;
 }
 .testimg{
    position:absolute;
    z-index:1;
    width:450px;
    height:338px;
    top:0px;
    left:0px
    
 }

3.JS代码

  1 $(document).ready(function(){        
  2         var pagewidth = document.body.clientWidth;//获取页面可用宽度
  3         $(".content").width(pagewidth*0.8);//设置css类为content标签div的宽度
  4         $(".testimg").width(pagewidth*0.8);//设置css类为testimg标签img的宽度
  5         $(".content").height($(".testimg").width()*0.75);//设置css类为content标签div的高度
  6         $(".testimg").height($(".testimg").width()*0.75);//设置css类为testimg标签img的高度
  7         imgInitialWidth = $(".testimg").width();//获取图片testimg的初始宽度
  8         imgInitialHeight = $(".testimg").height();//获取图片testimg的初始高度度        
  9         screenWidth = screen.width;//获取屏幕宽度
 10         screenHeight = screen.height;//获取屏幕高度
 11         screenDistance =  Math.sqrt(screenWidth*screenWidth+screenHeight*screenHeight);//根据屏幕分辨率获取屏幕对角线长    
 12   });
 13     var oneStartX;
 14     var oneStartY;
 15     var oneEndX;
 16     var oneEndY;  
 17     var twoStartX;
 18     var twoStartY;
 19     var twoEndX;
 20     var twoEndY;  
 21     var initialDistance;
 22     var moveDistance;
 23     var screenWidth;
 24     var screenHeight;
 25     var screenDistance;
 26     var radio;
 27     var base;
 28     var widthNow;
 29     var canvas = document.getElementById("body");//触摸有效的区域元素    
 30     var imgInitialWidth;
 31     var imgInitialHeight;
 32     var imgInitialTop;
 33     var imgInitialLeft;
 34     
 35     /*改变图片testimg的大小:当图片大小与初始大小一致时改变其大小,变为原来的2倍;否则恢复初始大小*/
 36    function change(){
 37         widthNow = $(".testimg").width();
 38         if(widthNow==imgInitialWidth){
 39             //改变图片大小为初始值的2倍,并移动图片使其在div中居中显示
 40             $(".testimg").animate({"width":imgInitialWidth*2,"height":imgInitialHeight*2,"top":-imgInitialHeight/2,"left":-imgInitialWidth/2},500);
 41         }
 42         else{
 43             //图片恢复初始大小
 44             $(".testimg").animate({"width":imgInitialWidth,"height":imgInitialHeight,"top":0,"left":0},500);
 45         }                    
 46    }
 47      
 48      /*开始触摸*/
 49     function touchStart(e) {
 50         //获取图片testimg的位置参数
 51         imgInitialTop = +$(".testimg").css("top").split('p')[0];        
 52         imgInitialLeft = +$(".testimg").css("left").split('p')[0];    
 53         var touches = e.targetTouches;    //获取位于设置dom元素上的手指动作列表       
 54         var  i = 0, l = touches.length,touch,touchId;
 55         if(l==1){
 56             oneStartX = touches[0].pageX;
 57             oneStartY = touches[0].pageY;      
 58         }
 59         //如果该元素上有俩个手指动作,分别获取手指动作所在坐标,并计算手指之间的初始距离
 60         if(l==2){
 61             oneStartX = touches[0].pageX;
 62             oneStartY = touches[0].pageY; 
 63             twoStartX = touches[1].pageX;
 64             twoStartY = touches[1].pageY;
 65             initialDistance = Math.sqrt((twoStartX-oneStartX)*(twoStartX-oneStartX)+(twoStartY-oneStartY)*(twoStartY-oneStartY));        
 66         }
 67         widthNow = $(".testimg").width();//获取图片testimg的即时宽度
 68     } 
 69     
 70      /*触摸移动*/
 71     function touchMove(e) {
 72        e.preventDefault();    //关闭触摸移动的默认动作    
 73        var touches = e.targetTouches;    //获取位于设置dom元素上的手指动作列表       
 74         var  i = 0, l = touches.length,touch,touchId;
 75         //如果设置dom元素上的只有一个手指动作,则该动作用于移动图片位置,并且只有在图片大小与初始大小不一致时生效
 76         if(l==1){        
 77         if(widthNow!=imgInitialWidth){
 78             var x = touches[0].pageX - oneStartX;
 79             var y = touches[0].pageY - oneStartY;
 80             var changeX =     imgInitialLeft+x;
 81             var changeY =     imgInitialTop+y;
 82             
 83             var imgWidthChange = $(".testimg").width()-imgInitialWidth;
 84             var imgHeightChange = $(".testimg").height()-imgInitialHeight;    
 85 
 86             if(changeX>0){
 87                 changeX = 0;
 88                 
 89             }else{
 90                 if(changeX*(-1)>imgWidthChange){
 91                     changeX = -imgWidthChange;
 92                 
 93                 }
 94             }
 95             if(changeY>0){
 96                 changeY = 0;
 97             }else{
 98                 if(changeY*(-1)>imgHeightChange){
 99                     changeY = -imgHeightChange;
100                 }
101             }                
102             $(".testimg").css({"top":changeY,"left":changeX});
103         }
104         base=1;
105         }
106         //如果设置dom元素上的有2个手指动作,则该动作用于确定移动后俩手指坐标
107         if(l==2){
108             oneEndX = touches[0].pageX;
109             oneEndY = touches[0].pageY; 
110             twoEndX = touches[1].pageX;
111             twoEndY = touches[1].pageY;        
112             base=2;
113         }        
114     }
115      /*触摸结束*/
116     function touchEnd(e) {        
117         //当设置dom元素上的有2个手指动作时,变换图片大小
118         if(base===2){
119             /*
120              *当移动后的俩手指距离大于触摸开始时的距离,及伸展触摸时,根据手指坐标取得的变换参数来确定图片的变换大小;
121              *当移动后的俩手指距离小于触摸开始时的距离,及收缩触摸时,图片恢复初始大小;
122              */
123             moveDistance = Math.sqrt((twoEndX-oneEndX)*(twoEndX-oneEndX)+(twoEndY-oneEndY)*(twoEndY-oneEndY));//移动后俩手指之间的距离
124             radio = (moveDistance-initialDistance)*40/screenDistance;//根据滑动距离和页面大小确定的变换参数,可以调整倍数来达到合适效果
125             if(moveDistance>initialDistance){
126             $(".testimg").animate({"width":imgInitialWidth*radio,"height":imgInitialHeight*radio,"top":-imgInitialHeight*(radio-1)/2,"left":-imgInitialWidth*(radio-1)/2},500);
127             }else{
128                 $(".testimg").animate({"width":imgInitialWidth,"height":imgInitialHeight,"top":0,"left":0},500);
129             }
130         }        
131     }
132 
133     canvas.addEventListener("touchstart", touchStart, false);//监听触摸启动事件
134     canvas.addEventListener("touchmove", touchMove, false);//监听滑动事件
135     canvas.addEventListener("touchend", touchEnd, false);//监听触摸结束事件
136     
137     //阻止body上的触摸默认事件,如翻页、滚动和缩放(有效性有待考证)
138     document.body.addEventListener('touchmove', function(event) {
139       event.preventDefault();
140     }, false);
View Code

 

   在线演示 

  整体思路为——事件双点触摸滑动改变图片大小:根据触摸双点前后距离差决定图片放大还是复原,根据俩个点触摸滑动的平均距离决定放大比例,并对应改变图片的top和left,及坐标,保证图片居中显示。事件单点触摸滑动移动图片位置:根据touch的坐标变化来改变图片的top和left,并设置极限值确保图片不会移出。需要注意的是只有 e.targetTouches才能获取到多个手指的坐标,不知道是什么原因。

 

二.使用js插件来模拟手势效果达到要求,可参考移动web开发,12个触摸及多点触摸事件常用Js插件,具体使用这里不讨论。

总结:

1.js插件功能强大,但是每一个的使用方法都有所不同,想要学会,要下一番功夫,并且定制功能在细节上有其局限性,无法满足某些需要;

2.自己写touch事件,会遇到很多问题,效果也不一定能尽人意,但是能学到更多的知识,而且如果真正理解透彻了,可以写自己的插件!

posted @ 2014-05-22 11:59  小小三师弟  阅读(624)  评论(0编辑  收藏  举报