基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解

  调用方式 :ImageView(index,imgData)  --index参数 为图片默认显示的索引值,类型 为Number  --imaData参数 为图片url数组 ,类型为Array

  使用之前要先引入 zepto.js 文件

  ImageView.js具体代码如下:

  

复制代码 代码如下:

  /*

  * ImageView v1.0.0

  * --基于zepto.js的大图查看

  * --调用方法 ImageView(index,imgDada)

  * --index 图片默认值显示索引,Number  --imgData 图片url数组,Array

  * */

  var ImageView=(function(window,$){

  var _this=$("#slideView"),_ImgData=[],_index=0,_length=0,

  _start=[],_org=[],_orgTime=null,

  _lastTapDate=null,

  _zoom=1,_zoomXY=[0,0],_transX=null,

  _advancedSupport = false,

  _doubleDistOrg=1,_doubleZoomOrg=1,isDoubleZoom = false,

  isSlide=true,isDrag=false,timer=null,

  winW=window.innerWidth,winH=window.innerHeight;

  /**

  * 事件对象 event

  */

  var Event={

  touchstart:function(e){

  e.preventDefault();

  if (_advancedSupport && e.touches && e.touches.length >= 2) {

  var img = getImg();

  $(img).css({"-webkit-transitionDuration": "0ms","transitionDuration": "0ms"});

  _doubleZoomOrg = _zoom;

  _doubleDistOrg = getDist(e.touches[0].pageX, e.touches[0].pageY, e.touches[1].pageX, e.touches[1].pageY);

  isDoubleZoom = true;

  return

  }

  e = e.touches ? e.touches[0] : e;

  isDoubleZoom = false;

  _start = [e.pageX, e.pageY];

  _org = [e.pageX, e.pageY];

  _orgTime = Date.now();

  _transX = -_index * winW;

  if(_zoom!=1){

  _zoomXY = _zoomXY || [0, 0];

  _orgZoomXY = [_zoomXY[0], _zoomXY[1]];

  var img = getImg();

  img&&($(img).css({"-webkit-transitionDuration": "0ms","transitionDuration": "0ms"}));

  isDrag = true

  }else{

  _this.find(".pv-inner").css({"-webkit-transitionDuration":"0ms","transitionDuration":"0ms"});

  isSlide = true

  }

  },

  touchmove:function(e){

  e.preventDefault();

  if (_advancedSupport && e.touches && e.touches.length >= 2) {

  var newDist = getDist(e.touches[0].pageX, e.touches[0].pageY, e.touches[1].pageX, e.touches[1].pageY);

  _zoom = (newDist/_doubleDistOrg) * _doubleZoomOrg

  var img = getImg();

  $(img).css({"-webkit-transitionDuration": "0ms","transitionDuration": "0ms"});

  if (_zoom < 1) {

  _zoom = 1;

  _zoomXY = [0, 0];

  $(img).css({"-webkit-transitionDuration": "200ms","transitionDuration": "200ms"})

  } else if (_zoom >getScale(img) * 2){

  _zoom = getScale(img) * 2;

  }

  $(img).css({"-webkit-transform": "scale(" + _zoom + ") translate(" + _zoomXY[0] + "px," + _zoomXY[1] + "px)","transform": "scale(" + _zoom + ") translate(" + _zoomXY[0] + "px," + _zoomXY[1] + "px)"});

  return

  }

  if (isDoubleZoom){

  return;

  }

  e = e.touches ? e.touches[0] : e;

  if (_zoom != 1) {

  var deltaX = (e.pageX - _start[0]) / _zoom;

  var deltaY = (e.pageY - _start[1]) / _zoom;

  _start = [e.pageX, e.pageY];

  var img = getImg();

  var newWidth = img.clientWidth *_zoom,

  newHeight = img.clientHeight * _zoom;

  var borderX = (newWidth - winW) / 2 / _zoom,

  borderY = (newHeight - winH) / 2 / _zoom;

  (borderX >= 0)&&(_zoomXY[0] < -borderX || _zoomXY[0] > borderX)&&(deltaX /= 3);

  (borderY > 0)&&(_zoomXY[1] < -borderY || _zoomXY[1] > borderY)&&(deltaY /= 3);

  _zoomXY[0] += deltaX;

  _zoomXY[1] += deltaY;

  (_length == 1 && newWidth < winW||newWidth < winW)&&(_zoomXY[0] = 0);

  (_length == 1 && newHeight < winH||newHeight < winH)&&(_zoomXY[1] = 0);

  $(img).css({"-webkit-transform": "scale(" + _zoom + ") translate(" + _zoomXY[0] +

  "px," + _zoomXY[1] + "px)","transform": "scale(" + _zoom + ") translate(" + _zoomXY[0] +

  "px," + _zoomXY[1] + "px)"})

  }else{

  if (!isSlide) return;

  var deltaX = e.pageX - _start[0];

  (_transX > 0 || _transX < -winW * (_length - 1))&&(deltaX /= 4);

  _transX = -_index * winW + deltaX;

  _this.find(".pv-inner").css({"-webkit-transform":"translate(" + _transX + "px,0px) translateZ(0)"});

  }

  },

  touchend:function(e){

  if (isDoubleZoom) {

  return;

  }

  if (_zoom != 1) {

  if (!isDrag){return;}

  var img = getImg();

  var newWidth = img.clientWidth *_zoom,

  newHeight = img.clientHeight * _zoom;

  var borderX = (newWidth - winW) / 2 / _zoom,

  borderY = (newHeight - winH) / 2 / _zoom;

  if (_length > 1 && borderX >= 0) {

  var updateDelta = 0;

  var switchDelta = winW / 6;

  if (_zoomXY[0] < -borderX - switchDelta / _zoom && _index < _length - 1){

  updateDelta = 1;

  }else if (_zoomXY[0] > borderX + switchDelta / _zoom && _index > 0){

  updateDelta = -1;

  }

  if (updateDelta != 0) {

  scaleDown(img);

  changeIndex(_index + updateDelta);

  return

  }

  }

  var delta = Date.now() - _orgTime;

  if (delta < 300) {

  (delta <= 10)&&(delta = 10);

  var deltaDis = Math.pow(180 / delta, 2);

  _zoomXY[0] += (_zoomXY[0] - _orgZoomXY[0]) * deltaDis;

  _zoomXY[1] += (_zoomXY[1] - _orgZoomXY[1]) * deltaDis;

  $(img).css({"-webkit-transition": "400ms cubic-bezier(0.08,0.65,0.79,1)","transition": "400ms cubic-bezier(0.08,0.65,0.79,1)"})

  } else{

  $(img).css({"-webkit-transition": "200ms linear","transition": "200ms linear"});

  }

  if (borderX >= 0){

  if (_zoomXY[0] < -borderX){

  _zoomXY[0] = -borderX;

  }else if (_zoomXY[0] > borderX){

  _zoomXY[0] = borderX;

  }

  }

  if (borderY > 0){

  if (_zoomXY[1] < -borderY){

  _zoomXY[1] = -borderY;

  }else if (_zoomXY[1] >borderY){

  _zoomXY[1] = borderY;

  }

  }

  if (Math.abs(_zoomXY[0]) < 10) {

  $(img).css({"-webkit-transform": "scale(" + _zoom + ") translate(0px," + _zoomXY[1] + "px)","transform": "scale(" + _zoom + ") translate(0px," + _zoomXY[1] + "px)"});

  return

  } else{

  $(img).css({"-webkit-transform": "scale(" + _zoom + ") translate(" + _zoomXY[0] + "px," + _zoomXY[1] + "px)","transform": "scale(" + _zoom + ") translate(" + _zoomXY[0] + "px," + _zoomXY[1] + "px)"});

  }

  isDrag = false

  }else{

  if (!isSlide){ return;}

  var deltaX = _transX - -_index * winW;

  var updateDelta = 0;

  if (deltaX > 50){

  updateDelta = -1;

  }else if(deltaX < -50){

  updateDelta = 1;

  }

  _index=_index+updateDelta;

  changeIndex(_index);

  isSlide =false

  }

  },

  click:function(e){

  _zoom=1;

  _zoomXY=[0,0];

  _this.css("opacity","0");

  timer=setTimeout(function(){

  _this.css({"display":""}).html("");

  unbind();

  },150)

  },

  dobelTap:function(e){

  clearTimeout(timer);

  var now = new Date;

  if (now - _lastTapDate < 500){

  return;

  }

  _lastTapDate = now;

  var img = getImg();

  if (!img){

  return;

  }

  if (_zoom != 1){

  scaleDown(img);

  }else{

  scaleUp(img);

  }

  },

  setView:function(e){

  winW=window.innerWidth;

  winH=window.innerHeight;

  _this.width(window.innerWidth).height(window.innerHeight);

  translate((-_index*window.innerWidth),0,0,$(".pv-inner")[0]);

  scaleDown(getImg())

  }

  };

  var handleEvent=function(e){

  switch (e.type){

  case "touchstart":

  Event.touchstart(e);

  break;

  case "touchmove":

  Event.touchmove(e);

  break;

  case "touchcancel":

  case "touchend":

  Event.touchend(e);

  break;

  case "orientationchange":

  case "resize":

  Event.setView(e);

  break

  }

  };

  /**

  * 绑定事件

  */

  var bind=function(){

  _this.on("singleTap",function(e){

  e.preventDefault();

  var now = new Date;

  if (now - _lastTapDate < 500){

  return;

  }

  _lastTapDate = now;

  Event.click(e);

  return false;

  }).on("doubleTap", function(e) {

  e.preventDefault();

  Event.dobelTap(e);

  return false;

  });

  _this.on("touchstart touchmove touchend touchcancel", function(e) {

  handleEvent(e);

  });

  Event.setView();

  "onorientationchange" in window ? window.addEventListener("orientationchange",Event.setView,false) : window.addEventListener("resize",Event.setView,false);

  };

  /**

  * 解除事件

  */

  var unbind= function() {

  _this.off();

  "onorientationchange" in window ? window.removeEventListener("orientationchange",Event.setView, false) : window.removeEventListener("resize",Event.setView, false)

  };

  var getDist= function(x1, y1, x2, y2) {

  return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2), 2)

  }

  /**

  * 图片缩放

  */

  var getScale=function(img) {

  var h = img.naturalHeight, w = img.naturalWidth,

  Scale=w*h/(img.clientHeight*img.clientWidth);

  return Scale;

  };

  var scaleUp=function(img) {

  var scale = getScale(img);

  if (scale > 1)

  $(img).css({"-webkit-transform": "scale(" + scale + ")","transform": "scale(" + scale + ")","-webkit-transition": "200ms","transition": "200ms"});

  _zoom = scale;

  };

  var scaleDown=function(img) {

  _zoom = 1;

  _zoomXY = [0, 0];

  _doubleDistOrg = 1;

  _doubleZoomOrg = 1;

  $(img).css({"-webkit-transform": "scale(1)","transform": "scale(1)","-webkit-transition": "200ms","transition": "200ms"});

  };

  /**

  * 滑动效果

  * dist

  */

  var translate = function( distX,distY,speed,ele) {

  if( !!ele ){ ele=ele.style; }else{ return; }

  ele.webkitTransitionDuration =  ele.MozTransitionDuration = ele.msTransitionDuration = ele.OTransitionDuration = ele.transitionDuration =  speed + 'ms';

  ele.webkitTransform = 'translate(' + distX + 'px,'+distY+'px)' + 'translateZ(0)';

  ele.msTransform = ele.MozTransform = ele.OTransform = 'translateX(' + distX + 'px) translateY(' + distY + 'px)';

  };

  /**

  * 更改索引值 _index

  */

  var changeIndex=function(index,force){

  if (index < 0){

  index = 0;

  }else if(index >= _length){

  index =_length - 1;

  }

  _index = index;

  translate((-_index*window.innerWidth),0,force? "0" : "200" ,$(".pv-inner")[0]);

  $("#J_index").html(_index+1+"/"+_length);

  imgLoad();

  }

  /**

  * 图片获取

  */

  var getImg=function(index) {

  var img = _this.find("li").eq(index || _index).find("img");

  if (img.size() == 1){

  return img[0];

  }else{

  return null

  }

  }

  /**

  * 图片加载

  */

  var imgLoad=function(){

  if($(".pv-img").eq(_index).find("img")[0]){

  $("#J_loading").css("display","");

  return;

  }else{

  $("#J_loading").css("display","block");

  var tempImg=new Image(),w,h,set;

  tempImg.src=_ImgData[_index];

  $(".pv-img").eq(_index)[0].appendChild(tempImg);

  tempImg.onload=function(){

  $("#J_loading").css("display","");

  }

  }

  };

  /**

  * 创建大图查看Dome结构

  */

  var Create=function(){

  _this.append("<ul class='pv-inner'></ul>").append("<p class='counts'><span class='value' id='J_index'>"+(_index+1)+"/"+_length+"</span></p>").append("<span class='ui-loading' id='J_loading' ><i class='t1'></i><i class='t2'></i><i class='t3'></i></span>")

  for(var i=0;i<_length;i++){

  $(".pv-inner").append("<li class='pv-img'></li>")

  }

  imgLoad();

  };

  /**

  * 大图查看初始化

  */

  var init=function(){

  !!_this[0]||$("body").append("<div class='slide-view' id='slideView'></div>");

  _this=$("#slideView");

  ($.os.iphone || $.os.android && parseFloat($.os.version) >= 4)&&(_advancedSupport = true);

  }();

  /**

  * 大图查看返回接口函数

  * ImageView(index,data)

  * index 初始索引值 nubmer

  * data 图片数组 array

  */

  var ImageView=function(index,data){

  _ImgData=data;

  _index=index;

  _length=data.length;

  //创建dom结构

  Create();

  //dom结构显示

  _this.css("display","block");

  //绑定事件

  bind();

  }

  return ImageView;

  })(window,Zepto);

  

  ImageView.js用到的css代码如下:

  

复制代码 代码如下:

  /*大图查看*/

  .slide-view {background: #000;position: fixed;width: 100%;height: 100%;overflow: hidden;top: 0;left: 0;z-index: 100;opacity:0;display: none;-webkit-animation:fadeIn .2s linear forwards;animation:fadeIn .2s linear forwards;-webkit-touch-callout: none;-webkit-transform-style: preserve-3d; }

  .slide-view .counts {position: absolute;top: 5%;left: 0;right: 0;text-align: center;font-size: 0;-webkit-transform-style: preserve-3d; }

  .slide-view .counts .value {border-radius: 9px;line-height: 18px;padding: 0 6px;font-size: 11px;display: inline-block;background-color: rgba(102,102,102,.6);color: #f1f1f1;}

  .pv-inner {position: relative;z-index: -1;display: -webkit-box;display: box;width: 100%;height: 100%;-webkit-transition: all 350ms linear;-webkit-backface-visibility: hidden;transition: all 350ms linear;backface-visibility: hidden;-webkit-touch-callout: none;-webkit-transform-style: preserve-3d; }

  .pv-inner li {text-align: center;display: -webkit-box;display: box;-webkit-box-align: center;overflow: hidden;width: 100%;height: 100%;-webkit-touch-callout: none;backface-visibility: hidden;-webkit-transform-style: preserve-3d; }

  .pv-inner img {max-width: 97%;max-height: 100%;-webkit-transform: scale(1) translate(0px,0px);transform: scale(1) translate(0px,0px);visibility: visible;-webkit-transition: 200ms;transition: 200ms;-webkit-user-select: none;user-select: none;display: block;margin: 0 auto;backface-visibility: hidden;-webkit-transform-style: preserve-3d; }

  @-webkit-keyframes fadeIn{

  0%{opacity:0;}

  100%{opacity:1;}

  }

  @keyframes fadeIn{

  0%{opacity:0;}

  100%{opacity:100%;}

  }

  /*--------------------loading-----------------------*/

  .ui-loading {position: absolute;left: 50%;top: 50%;display: none;vertical-align: middle;font: 0/0 arial;margin: -5px 0 0 -10px;}

  .ui-loading i {display: inline-block;width: 5px;height: 12px;background: #fff;vertical-align: top;-webkit-animation: loading-spin 1s infinite linear;animation: loading-spin 1s infinite linear;}

  .ui-loading i {-webkit-animation: loading-spin 1s infinite linear;animation: loading-spin 1s infinite linear}

  .ui-loading i.t2 {margin: 0 3px;-webkit-animation-name: loading-spin-one;animation-name: loading-spin-one}

  .ui-loading i.t3 {-webkit-animation-name: loading-spin-two;animation-name: loading-spin-two}

  @-webkit-keyframes loading-spin {

  0% {opacity: 0}

  30% {opacity: 1;-webkit-transform: scale(1,1.2)}

  60% {opacity: 0;-webkit-transform: scale(1)}

  100% {opacity: 0}

  }

  @-webkit-keyframes loading-spin-one {

  0% {opacity: 0}

  20% {opacity: 0}

  50% {opacity: 1;-webkit-transform: scale(1,1.2)}

  80% {opacity: 0;-webkit-transform: scale(1)}

  100% {opacity: 0}

  }

  @-webkit-keyframes loading-spin-two {

  0% {opacity: 0}

  40% {opacity: 0}

  70% {opacity: 1;-webkit-transform: scale(1,1.2)}

  100% {opacity: 0;-webkit-transform: scale(1)}

  }

  @keyframes loading-spin {

  0% {opacity: 0}

  30% {opacity: 1;transform: scale(1,1.2)}

  60% {opacity: 0;transform: scale(1)}

  100% {opacity: 0}

  }

  @keyframes loading-spin-one {

  0% {opacity: 0}

  20% {opacity: 0}

  50% {opacity: 1;transform: scale(1,1.2)}

  80% {opacity: 0;transform: scale(1)}

  100% {opacity: 0}

  }

  @keyframes loading-spin-two {

  0% {opacity: 0}

  40% {opacity: 0}

  70% {opacity: 1;transform: scale(1,1.2)}

  100% {opacity: 0;transform: scale(1)}

  }

  /*--------------------loading-end----------------------*/

  ps:代码功能比较简单,可能会存在诸多问题。但也能勉强使用了

  下用是使用ImageView.js的一个例子:

  

复制代码 代码如下:

  <!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>

  <script type="text/javascript" src="test_files/zepto.min.js" ></script>

  <script type="text/javascript" src="test_files/ImageView.js" ></script>

  </head>

  <body>

  <!--以上为HTML页面结构 -->

  <!--以下为ImageView使用例子 -->

  <script>

  ;(function(){

  //获取 html 中的图片元素

  var aImg=document.querySelectorAll("img"),

  aImgSrc=[];

  //为图片绑定单击事件

  for(var i=0,l=aImg.length;i<l;i++){

  aImg[i].index=i;

  aImg[i].className+=" conPic";

  aImgSrc.push(aImg[i].src);

  }

  for(var i=0;i<$(".conPic").length;i++){

  if($(".conPic")[i].complete){

  addTap($(".conPic")[i])

  }else{

  $(".conPic")[i].onload=function(){

  addTap(this);

  }

  }

  }

  function addTap(obj){

  $(obj).on("tap",function(){

  //调用ImageView

  ImageView($(obj)[0].index,aImgSrc);

  })

  }

  })();

  </script>

  </body>

  以上就是本文的全部内容了,希望大家能够喜欢