scale.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. function getTranslate(x, y){
  8. var distX = x, distY = y;
  9. return support.transform3d ? "translate3d("+ distX +"px, "+ distY +"px, 0)" : "translate("+ distX +"px, "+ distY +"px)";
  10. }
  11. function getPage(event, page) {
  12. return support.touch ? event.changedTouches[0][page] : event[page];
  13. }
  14. var ImagesZoom = function(){};
  15. ImagesZoom.prototype = {
  16. // 给初始化数据
  17. init: function(param){
  18. var self = this,
  19. params = param || {},
  20. imgIndex = 0;
  21. var imgList = document.querySelectorAll(params.elem + " img"),
  22. zoomMask = document.querySelector(".imgzoom-pack"),
  23. zoomImg = document.querySelector(".imgzoom-pack .imgzoom-img img"),
  24. zoomClose = document.querySelector(".imgzoom-pack .imgzoom-x"),
  25. zoomDel = document.querySelector(".imgzoom-pack .imgzoom-del"),
  26. imgSrc = "";
  27. self.buffMove = 3; //缓冲系数
  28. self.buffScale = 2; //放大系数
  29. self.finger = false; //触摸手指的状态 false:单手指 true:多手指
  30. self._destroy();
  31. zoomClose.addEventListener("click", function(){
  32. zoomMask.style.cssText = "display:none";
  33. zoomImg.src = "";
  34. zoomImg.style.cssText = "";
  35. self._destroy();
  36. document.removeEventListener("touchmove", self.eventStop, false);
  37. }, false);
  38. zoomDel.addEventListener("click", function(){
  39. zoomMask.style.cssText = "display:none";
  40. zoomImg.src = "";
  41. zoomImg.style.cssText = "";
  42. var imgLi=document.querySelectorAll(params.elem + " li");
  43. if(params.delBack){
  44. params.delBack(imgIndex);
  45. };
  46. self._destroy();
  47. document.removeEventListener("touchmove", self.eventStop, false);
  48. }, false);
  49. for(var len=imgList.length,i=0; i<len; i++){
  50. imgList[i].addEventListener("click", function(){
  51. imgIndex=$(this).parent().index();
  52. imgSrc = this.getAttribute("src");
  53. zoomMask.style.cssText = "display:block";
  54. zoomImg.src = imgSrc;
  55. zoomImg.onload = function(){
  56. zoomImg.style.cssText = "margin-top:-"+(zoomImg.offsetHeight/2)+"px";
  57. // 禁止页面滚动
  58. document.addEventListener("touchmove", self.eventStop, false);
  59. self.imgBaseWidth = zoomImg.offsetWidth;
  60. self.imgBaseHeight = zoomImg.offsetHeight;
  61. self.addEventStart({
  62. wrapX: zoomMask.offsetWidth,
  63. wrapY: zoomMask.offsetHeight,
  64. mapX: zoomImg.width,
  65. mapY: zoomImg.height
  66. });
  67. }
  68. }, false);
  69. }
  70. },
  71. addEventStart: function(param){
  72. var self = this,
  73. params = param || {};
  74. self.element = document.querySelector(".imgzoom-pack img");
  75. //config set
  76. self.wrapX = params.wrapX || 0; //可视区域宽度
  77. self.wrapY = params.wrapY || 0; //可视区域高度
  78. self.mapX = params.mapX || 0; //地图宽度
  79. self.mapY = params.mapY || 0; //地图高度
  80. self.outDistY = (self.mapY - self.wrapY)/2; //图片超过一屏的时候有用
  81. self.width = self.mapX - self.wrapX; //地图的宽度减去可视区域的宽度
  82. self.height = self.mapY - self.wrapY; //地图的高度减去可视区域的高度
  83. self.element.addEventListener("touchstart",function(e){
  84. self._touchstart(e);
  85. },false);
  86. self.element.addEventListener("touchmove",function(e){
  87. self._touchmove(e);
  88. },false);
  89. self.element.addEventListener("touchend",function(e){
  90. self._touchend(e);
  91. },false);
  92. },
  93. // 重置坐标数据
  94. _destroy: function(){
  95. this.distX = 0;
  96. this.distY = 0;
  97. this.newX = 0;
  98. this.newY = 0;
  99. },
  100. // 更新地图信息
  101. _changeData: function(){
  102. this.mapX = this.element.offsetWidth; //地图宽度
  103. this.mapY = this.element.offsetHeight; //地图高度
  104. // this.outDistY = (this.mapY - this.wrapY)/2; //当图片高度超过屏幕的高度时候。图片是垂直居中的,这时移动有个高度做为缓冲带
  105. this.width = this.mapX - this.wrapX; //地图的宽度减去可视区域的宽度
  106. this.height = this.mapY - this.wrapY; //地图的高度减去可视区域的高度
  107. },
  108. _touchstart: function(e){
  109. var self = this;
  110. e.preventDefault();
  111. var touchTarget = e.targetTouches.length; //获得触控点数
  112. self._changeData(); //重新初始化图片、可视区域数据,由于放大会产生新的计算
  113. if(touchTarget == 1){
  114. // 获取开始坐标
  115. self.basePageX = getPage(e, "pageX");
  116. self.basePageY = getPage(e, "pageY");
  117. self.finger = false;
  118. }else{
  119. self.finger = true;
  120. self.startFingerDist = self.getTouchDist(e).dist;
  121. self.startFingerX = self.getTouchDist(e).x;
  122. self.startFingerY = self.getTouchDist(e).y;
  123. }
  124. console.log("pageX: "+getPage(e, "pageX"));
  125. console.log("pageY: "+getPage(e, "pageY"));
  126. },
  127. _touchmove: function(e){
  128. var self = this;
  129. e.preventDefault();
  130. e.stopPropagation();
  131. console.log("event.changedTouches[0].pageY: "+event.changedTouches[0].pageY);
  132. var touchTarget = e.targetTouches.length; //获得触控点数
  133. if(touchTarget == 1 && !self.finger){
  134. self._move(e);
  135. }
  136. if(touchTarget>=2){
  137. self._zoom(e);
  138. }
  139. },
  140. _touchend: function(e){
  141. var self = this;
  142. self._changeData(); //重新计算数据
  143. if(self.finger){
  144. self.distX = -self.imgNewX;
  145. self.distY = -self.imgNewY;
  146. }
  147. if( self.distX>0 ){
  148. self.newX = 0;
  149. }else if( self.distX<=0 && self.distX>=-self.width ){
  150. self.newX = self.distX;
  151. self.newY = self.distY;
  152. }else if( self.distX<-self.width ){
  153. self.newX = -self.width;
  154. }
  155. self.reset();
  156. },
  157. _move: function(e){
  158. var self = this,
  159. pageX = getPage(e, "pageX"), //获取移动坐标
  160. pageY = getPage(e, "pageY");
  161. // 禁止默认事件
  162. // e.preventDefault();
  163. // e.stopPropagation();
  164. // 获得移动距离
  165. self.distX = (pageX - self.basePageX) + self.newX;
  166. self.distY = (pageY - self.basePageY) + self.newY;
  167. if(self.distX > 0){
  168. self.moveX = Math.round(self.distX/self.buffMove);
  169. }else if( self.distX<=0 && self.distX>=-self.width ){
  170. self.moveX = self.distX;
  171. }else if(self.distX < -self.width ){
  172. self.moveX = -self.width+Math.round((self.distX+self.width)/self.buffMove);
  173. }
  174. self.movePos();
  175. self.finger = false;
  176. },
  177. // 图片缩放
  178. _zoom: function(e){
  179. var self = this;
  180. // e.preventDefault();
  181. // e.stopPropagation();
  182. var nowFingerDist = self.getTouchDist(e).dist, //获得当前长度
  183. ratio = nowFingerDist / self.startFingerDist, //计算缩放比
  184. imgWidth = Math.round(self.mapX * ratio), //计算图片宽度
  185. imgHeight = Math.round(self.mapY * ratio); //计算图片高度
  186. // 计算图片新的坐标
  187. self.imgNewX = Math.round(self.startFingerX * ratio - self.startFingerX - self.newX * ratio);
  188. self.imgNewY = Math.round((self.startFingerY * ratio - self.startFingerY)/2 - self.newY * ratio);
  189. if(imgWidth >= self.imgBaseWidth){
  190. self.element.style.width = imgWidth + "px";
  191. self.refresh(-self.imgNewX, -self.imgNewY, "0s", "ease");
  192. self.finger = true;
  193. }else{
  194. if(imgWidth < self.imgBaseWidth){
  195. self.element.style.width = self.imgBaseWidth + "px";
  196. }
  197. }
  198. self.finger = true;
  199. },
  200. // 移动坐标
  201. movePos: function(){
  202. var self = this;
  203. if(self.height<0){
  204. if(self.element.offsetWidth == self.imgBaseWidth){
  205. self.moveY = Math.round(self.distY/self.buffMove);
  206. }else{
  207. var moveTop = Math.round((self.element.offsetHeight-self.imgBaseHeight)/2);
  208. self.moveY = -moveTop + Math.round((self.distY + moveTop)/self.buffMove);
  209. }
  210. }else{
  211. var a = Math.round((self.wrapY - self.imgBaseHeight)/2),
  212. b = self.element.offsetHeight - self.wrapY + Math.round(self.wrapY - self.imgBaseHeight)/2;
  213. if(self.distY >= -a){
  214. self.moveY = Math.round((self.distY + a)/self.buffMove) - a;
  215. }else if(self.distY <= -b){
  216. self.moveY = Math.round((self.distY + b)/self.buffMove) - b;
  217. }else{
  218. self.moveY = self.distY;
  219. }
  220. }
  221. self.refresh(self.moveX, self.moveY, "0s", "ease");
  222. },
  223. // 重置数据
  224. reset: function(){
  225. var self = this,
  226. hideTime = ".2s";
  227. if(self.height<0){
  228. self.newY = -Math.round(self.element.offsetHeight - self.imgBaseHeight)/2;
  229. }else{
  230. var a = Math.round((self.wrapY - self.imgBaseHeight)/2),
  231. b = self.element.offsetHeight - self.wrapY + Math.round(self.wrapY - self.imgBaseHeight)/2;
  232. if(self.distY >= -a){
  233. self.newY = -a;
  234. }else if(self.distY <= -b){
  235. self.newY = -b;
  236. }else{
  237. self.newY = self.distY;
  238. }
  239. }
  240. self.refresh(self.newX, self.newY, hideTime, "ease-in-out");
  241. },
  242. // 执行图片移动
  243. refresh: function(x, y, timer, type){
  244. this.element.style.webkitTransitionProperty = "-webkit-transform";
  245. this.element.style.webkitTransitionDuration = timer;
  246. this.element.style.webkitTransitionTimingFunction = type;
  247. this.element.style.webkitTransform = getTranslate(x, y);
  248. },
  249. // 获取多点触控
  250. getTouchDist: function(e){
  251. var x1 = 0,
  252. y1 = 0,
  253. x2 = 0,
  254. y2 = 0,
  255. x3 = 0,
  256. y3 = 0,
  257. result = {};
  258. x1 = e.touches[0].pageX;
  259. x2 = e.touches[1].pageX;
  260. y1 = e.touches[0].pageY - document.body.scrollTop;
  261. y2 = e.touches[1].pageY - document.body.scrollTop;
  262. if(!x1 || !x2) return;
  263. if(x1<=x2){
  264. x3 = (x2-x1)/2+x1;
  265. }else{
  266. x3 = (x1-x2)/2+x2;
  267. }
  268. if(y1<=y2){
  269. y3 = (y2-y1)/2+y1;
  270. }else{
  271. y3 = (y1-y2)/2+y2;
  272. }
  273. result = {
  274. dist: Math.round(Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2))),
  275. x: Math.round(x3),
  276. y: Math.round(y3)
  277. };
  278. return result;
  279. },
  280. eventStop: function(e){
  281. e.preventDefault();
  282. e.stopPropagation();
  283. }
  284. };
  285. window.ImagesZoom = new ImagesZoom();
  286. })(this);