在移动设备上放大图片查看图片细节的俩种方法
类似淘宝京东上的产品图,我们可以放大来看产品的具体细节。那么,在移动设备上,基于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);
整体思路为——事件双点触摸滑动改变图片大小:根据触摸双点前后距离差决定图片放大还是复原,根据俩个点触摸滑动的平均距离决定放大比例,并对应改变图片的top和left,及坐标,保证图片居中显示。事件单点触摸滑动移动图片位置:根据touch的坐标变化来改变图片的top和left,并设置极限值确保图片不会移出。需要注意的是只有 e.targetTouches才能获取到多个手指的坐标,不知道是什么原因。
二.使用js插件来模拟手势效果达到要求,可参考移动web开发,12个触摸及多点触摸事件常用Js插件,具体使用这里不讨论。
总结:
1.js插件功能强大,但是每一个的使用方法都有所不同,想要学会,要下一番功夫,并且定制功能在细节上有其局限性,无法满足某些需要;
2.自己写touch事件,会遇到很多问题,效果也不一定能尽人意,但是能学到更多的知识,而且如果真正理解透彻了,可以写自己的插件!