移动端单击图片放大,缩小
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>图片缩放</title> <link rel="stylesheet" type="text/css" href="scale.css" /> <script src="../../js/scale.js" type="text/javascript" charset="utf-8"></script> <style type="text/css"> .list img{ width: 200px; height: 200px; } /*弹框样式*/ .imgzoom_pack{ width:100%; height:100%; position:fixed; left:0; top:0; background:rgba(0,0,0,.6); display:none; } .imgzoom_pack .imgzoom_x{ color:#fff; height:30px; width:30px; line-height:30px; background:#000; text-align:center; position:absolute; right:5px; top:5px; z-index:10; cursor:pointer; } .imgzoom_pack .imgzoom_img{ width:100%; height:100%; position:absolute; left:0; top:0; overflow:hidden; } .imgzoom_pack .imgzoom_img img{ width:100%; position:absolute; top:50%; } </style> </head> <body> <div class="list"> <img src="../../img/biyadi.jpg" /> <img src="../../img/biyadi.jpg" /> </div> <section class="imgzoom_pack"> <div class="imgzoom_x">X</div> <div class="imgzoom_img"><img src="" /></div> </section> <script src="scale.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> document.addEventListener("DOMContentLoaded", function(event) { ImagesZoom.init({ "elem": ".list" }); }, false); </script> </body> </html> js部分 scale.js
1 (function(window, undefined){ 2 var document = window.document, 3 support = { 4 transform3d: ("WebKitCSSMatrix" in window && "m11" in new WebKitCSSMatrix()), 5 touch: ("ontouchstart" in window) 6 }; 7 8 function getTranslate(x, y){ 9 var distX = x, distY = y; 10 return support.transform3d ? "translate3d("+ distX +"px, "+ distY +"px, 0)" : "translate("+ distX +"px, "+ distY +"px)"; 11 } 12 13 14 function getPage(event, page) { 15 return support.touch ? event.changedTouches[0][page] : event[page]; 16 } 17 18 19 var ImagesZoom = function(){}; 20 21 22 ImagesZoom.prototype = { 23 // 给初始化数据 24 init: function(param){ 25 var self = this, 26 params = param || {}; 27 28 var imgList = document.querySelectorAll(params.elem + " img"), 29 zoomMask = document.querySelector(".imgzoom_pack"), 30 zoomImg = document.querySelector(".imgzoom_pack .imgzoom_img img"), 31 zoomClose = document.querySelector(".imgzoom_pack .imgzoom_x"), 32 imgSrc = ""; 33 34 35 self.buffMove = 3; //缓冲系数 36 self.buffScale = 2; //放大系数 37 self.finger = false; //触摸手指的状态 false:单手指 true:多手指 38 39 self._destroy(); 40 41 42 zoomClose.addEventListener("click", function(){ 43 zoomMask.style.cssText = "display:none"; 44 zoomImg.src = ""; 45 zoomImg.style.cssText = ""; 46 47 48 self._destroy(); 49 50 51 document.removeEventListener("touchmove", self.eventStop, false); 52 }, false); 53 54 55 for(var len=imgList.length,i=0; i<len; i++){ 56 imgList[i].addEventListener("click", function(){ 57 imgSrc = this.getAttribute("src"); 58 zoomMask.style.cssText = "display:block"; 59 zoomImg.src = imgSrc; 60 61 62 zoomImg.onload = function(){ 63 zoomImg.style.cssText = "margin-top:-"+(zoomImg.offsetHeight/2)+"px"; 64 65 66 // 禁止页面滚动 67 document.addEventListener("touchmove", self.eventStop, false); 68 69 self.imgBaseWidth = zoomImg.offsetWidth; 70 self.imgBaseHeight = zoomImg.offsetHeight; 71 72 73 self.addEventStart({ 74 wrapX: zoomMask.offsetWidth, 75 wrapY: zoomMask.offsetHeight, 76 mapX: zoomImg.width, 77 mapY: zoomImg.height 78 }); 79 } 80 }, false); 81 } 82 }, 83 addEventStart: function(param){ 84 var self = this, 85 params = param || {}; 86 87 88 self.element = document.querySelector(".imgzoom_pack img"); 89 90 91 //config set 92 self.wrapX = params.wrapX || 0; //可视区域宽度 93 self.wrapY = params.wrapY || 0; //可视区域高度 94 self.mapX = params.mapX || 0; //地图宽度 95 self.mapY = params.mapY || 0; //地图高度 96 97 98 self.outDistY = (self.mapY - self.wrapY)/2; //图片超过一屏的时候有用 99 100 self.width = self.mapX - self.wrapX; //地图的宽度减去可视区域的宽度 101 self.height = self.mapY - self.wrapY; //地图的高度减去可视区域的高度 102 103 104 self.element.addEventListener("touchstart",function(e){ 105 self._touchstart(e); 106 },false); 107 self.element.addEventListener("touchmove",function(e){ 108 self._touchmove(e); 109 },false); 110 self.element.addEventListener("touchend",function(e){ 111 self._touchend(e); 112 },false); 113 }, 114 // 重置坐标数据 115 _destroy: function(){ 116 this.distX = 0; 117 this.distY = 0; 118 this.newX = 0; 119 this.newY = 0; 120 }, 121 // 更新地图信息 122 _changeData: function(){ 123 this.mapX = this.element.offsetWidth; //地图宽度 124 this.mapY = this.element.offsetHeight; //地图高度 125 // this.outDistY = (this.mapY - this.wrapY)/2; //当图片高度超过屏幕的高度时候。图片是垂直居中的,这时移动有个高度做为缓冲带 126 this.width = this.mapX - this.wrapX; //地图的宽度减去可视区域的宽度 127 this.height = this.mapY - this.wrapY; //地图的高度减去可视区域的高度 128 }, 129 _touchstart: function(e){ 130 var self = this; 131 132 133 e.preventDefault(); 134 135 136 var touchTarget = e.targetTouches.length; //获得触控点数 137 138 139 self._changeData(); //重新初始化图片、可视区域数据,由于放大会产生新的计算 140 141 142 if(touchTarget == 1){ 143 // 获取开始坐标 144 self.basePageX = getPage(e, "pageX"); 145 self.basePageY = getPage(e, "pageY"); 146 147 148 self.finger = false; 149 }else{ 150 self.finger = true; 151 152 153 self.startFingerDist = self.getTouchDist(e).dist; 154 self.startFingerX = self.getTouchDist(e).x; 155 self.startFingerY = self.getTouchDist(e).y; 156 } 157 158 159 console.log("pageX: "+getPage(e, "pageX")); 160 console.log("pageY: "+getPage(e, "pageY")); 161 }, 162 _touchmove: function(e){ 163 var self = this; 164 165 166 e.preventDefault(); 167 e.stopPropagation(); 168 169 170 console.log("event.changedTouches[0].pageY: "+event.changedTouches[0].pageY); 171 172 var touchTarget = e.targetTouches.length; //获得触控点数 173 174 175 if(touchTarget == 1 && !self.finger){ 176 self._move(e); 177 } 178 179 180 if(touchTarget>=2){ 181 self._zoom(e); 182 } 183 }, 184 _touchend: function(e){ 185 var self = this; 186 187 188 self._changeData(); //重新计算数据 189 if(self.finger){ 190 self.distX = -self.imgNewX; 191 self.distY = -self.imgNewY; 192 } 193 194 195 if( self.distX>0 ){ 196 self.newX = 0; 197 }else if( self.distX<=0 && self.distX>=-self.width ){ 198 self.newX = self.distX; 199 self.newY = self.distY; 200 }else if( self.distX<-self.width ){ 201 self.newX = -self.width; 202 } 203 self.reset(); 204 }, 205 _move: function(e){ 206 var self = this, 207 pageX = getPage(e, "pageX"), //获取移动坐标 208 pageY = getPage(e, "pageY"); 209 210 211 // 禁止默认事件 212 // e.preventDefault(); 213 // e.stopPropagation(); 214 215 216 // 获得移动距离 217 self.distX = (pageX - self.basePageX) + self.newX; 218 self.distY = (pageY - self.basePageY) + self.newY; 219 220 221 if(self.distX > 0){ 222 self.moveX = Math.round(self.distX/self.buffMove); 223 }else if( self.distX<=0 && self.distX>=-self.width ){ 224 self.moveX = self.distX; 225 }else if(self.distX < -self.width ){ 226 self.moveX = -self.width+Math.round((self.distX+self.width)/self.buffMove); 227 } 228 self.movePos(); 229 self.finger = false; 230 }, 231 // 图片缩放 232 _zoom: function(e){ 233 var self = this; 234 // e.preventDefault(); 235 // e.stopPropagation(); 236 237 238 var nowFingerDist = self.getTouchDist(e).dist, //获得当前长度 239 ratio = nowFingerDist / self.startFingerDist, //计算缩放比 240 imgWidth = Math.round(self.mapX * ratio), //计算图片宽度 241 imgHeight = Math.round(self.mapY * ratio); //计算图片高度 242 243 244 // 计算图片新的坐标 245 self.imgNewX = Math.round(self.startFingerX * ratio - self.startFingerX - self.newX * ratio); 246 self.imgNewY = Math.round((self.startFingerY * ratio - self.startFingerY)/2 - self.newY * ratio); 247 248 249 if(imgWidth >= self.imgBaseWidth){ 250 self.element.style.width = imgWidth + "px"; 251 self.refresh(-self.imgNewX, -self.imgNewY, "0s", "ease"); 252 self.finger = true; 253 }else{ 254 if(imgWidth < self.imgBaseWidth){ 255 self.element.style.width = self.imgBaseWidth + "px"; 256 } 257 } 258 259 260 self.finger = true; 261 }, 262 // 移动坐标 263 movePos: function(){ 264 var self = this; 265 266 267 if(self.height<0){ 268 if(self.element.offsetWidth == self.imgBaseWidth){ 269 self.moveY = Math.round(self.distY/self.buffMove); 270 }else{ 271 var moveTop = Math.round((self.element.offsetHeight-self.imgBaseHeight)/2); 272 self.moveY = -moveTop + Math.round((self.distY + moveTop)/self.buffMove); 273 } 274 }else{ 275 var a = Math.round((self.wrapY - self.imgBaseHeight)/2), 276 b = self.element.offsetHeight - self.wrapY + Math.round(self.wrapY - self.imgBaseHeight)/2; 277 278 279 if(self.distY >= -a){ 280 self.moveY = Math.round((self.distY + a)/self.buffMove) - a; 281 }else if(self.distY <= -b){ 282 self.moveY = Math.round((self.distY + b)/self.buffMove) - b; 283 }else{ 284 self.moveY = self.distY; 285 } 286 } 287 self.refresh(self.moveX, self.moveY, "0s", "ease"); 288 }, 289 // 重置数据 290 reset: function(){ 291 var self = this, 292 hideTime = ".2s"; 293 if(self.height<0){ 294 self.newY = -Math.round(self.element.offsetHeight - self.imgBaseHeight)/2; 295 }else{ 296 var a = Math.round((self.wrapY - self.imgBaseHeight)/2), 297 b = self.element.offsetHeight - self.wrapY + Math.round(self.wrapY - self.imgBaseHeight)/2; 298 299 300 if(self.distY >= -a){ 301 self.newY = -a; 302 }else if(self.distY <= -b){ 303 self.newY = -b; 304 }else{ 305 self.newY = self.distY; 306 } 307 } 308 self.refresh(self.newX, self.newY, hideTime, "ease-in-out"); 309 }, 310 // 执行图片移动 311 refresh: function(x, y, timer, type){ 312 this.element.style.webkitTransitionProperty = "-webkit-transform"; 313 this.element.style.webkitTransitionDuration = timer; 314 this.element.style.webkitTransitionTimingFunction = type; 315 this.element.style.webkitTransform = getTranslate(x, y); 316 }, 317 // 获取多点触控 318 getTouchDist: function(e){ 319 var x1 = 0, 320 y1 = 0, 321 x2 = 0, 322 y2 = 0, 323 x3 = 0, 324 y3 = 0, 325 result = {}; 326 327 328 x1 = e.touches[0].pageX; 329 x2 = e.touches[1].pageX; 330 y1 = e.touches[0].pageY - document.body.scrollTop; 331 y2 = e.touches[1].pageY - document.body.scrollTop; 332 333 334 if(!x1 || !x2) return; 335 336 337 if(x1<=x2){ 338 x3 = (x2-x1)/2+x1; 339 }else{ 340 x3 = (x1-x2)/2+x2; 341 } 342 if(y1<=y2){ 343 y3 = (y2-y1)/2+y1; 344 }else{ 345 y3 = (y1-y2)/2+y2; 346 } 347 348 349 result = { 350 dist: Math.round(Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2))), 351 x: Math.round(x3), 352 y: Math.round(y3) 353 }; 354 return result; 355 }, 356 eventStop: function(e){ 357 e.preventDefault(); 358 e.stopPropagation(); 359 } 360 }; 361 362 363 window.ImagesZoom = new ImagesZoom(); 364 })(this);