基于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>

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

(0)

相关推荐

  • touch.js 拖动、缩放、旋转 (鼠标手势)功能代码

    可以实现手势操作:拖动.缩放.旋转.封装好的脚本方法是这样的: var cat = window.cat || {}; cat.touchjs = { left: 0, top: 0, scaleVal: 1, //缩放 rotateVal: 0, //旋转 curStatus: 0, //记录当前手势的状态, 0:拖动, 1:缩放, 2:旋转 //初始化 init: function ($targetObj, callback) { touch.on($targetObj, 'touchsta

  • 移动端js触摸事件详解

    在移动开发中,一种较为容易的做法是,先在桌面上开始原型设计,然后再在打算要支持的设备上处理移动特有的部分.多点触摸正是难以在PC上进行测试的那些功能之一,因为大部分的PC都没有触摸输入. 不得不在移动设备上进行的测试有可能会拉长你的开发周期,因为你所做的每项改变都需要提交代码到服务器上,接着再加载到设备上.然后,一旦运行后,对应用也就没有太多的调试了,因为平板电脑和智能手机都很缺乏web开发者所用的工具. 这个问题的一个解决方案是在开发机器上模拟触发事件.对于单点触摸,触摸事件可以基于鼠标事件来

  • 移动端脚本框架Hammer.js

    一.前言 移动端框架当前还处在初级阶段,但相对于移动端的应用来说已经有很长时间了.虽然暂时还没有PC端开发的需求量大,但移动端的Web必然是一种趋势,在接触移动端脚本的过程中,最开始想到的是juqery.Jquery2.0版本及以上已经开始偏向移动端,如对h5的支持,但支持还是不够完善,希望jq在后面的版本能够逐渐支持起来. 最初在开发移动端Web的时候使用w3c标准的语法结构和原生的js开发,但相对来说开发量比较大,而且每一步都要考虑各移动端浏览器的兼容,像比较让程序员头痛的大wp手机,很多事

  • Hammer.js+轮播原理实现简洁的滑屏功能

    最近有个任务,做一个非常小的h5的应用,只有2屏,需要做横向的全屏滑动切换和一些简单的动画效果,之前做这种东西用的是fullpage.js和jquery,性能不是很好,于是就想自己动手弄一个简单的东西来实现.最后我用zepto + hammer.js 和轮播的方式解决了这个问题,效果还不错,整个页面不开启Gzip时所有资源请求的数据大小为200KB左右.这篇文章总结下这个方法的实现思路. 效果演示: 1. 实现要点 1)滑屏借鉴bootstrap的carousel插件,不过完全没有它那个复杂,只

  • 浅谈移动端之js touch事件 手势滑动事件

    现分享一篇关于touch的文章,望指教! 原理: 当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和纵坐标startY: 当触发touchmove事件时,在获取此时手指的横坐标moveEndX和纵坐标moveEndY;最后,通过这两次获取的坐标差值来判断手指在手机屏幕上的滑动方向. 具体代码如下: $("body").on("touchstart", function(e) { e.preventDefault(); startX = e.

  • zepto.js中tap事件阻止冒泡的实现方法

    本文实例讲述了zepto.js中tap事件阻止冒泡的实现方法.分享给大家供大家参考.具体如下: 最近在弄一个手机版的网站,本来想用jQuery Mobile,但文件太大了,所以用了zepto.js 由于移动网页中使用click事件会有延迟,所以就用上了zepto.js中的tap事件. 使用click事件可以使用stopPropagation来阻止冒泡,但tap使用该方法无效 现在我需要实现这样一个效果:点击a.btn这个按钮,然后显示div.panel,当我点击非div.panel时隐藏div.

  • jQuery插件zepto.js简单实现tab切换

    老规矩,先贴代码 <script> $(function(){ window.onload = function() { var $li = $('.taocan-title li'); var $ul = $('.taocan-content .con110'); $li.mouseover(function(){ var $this = $(this); var $t = $this.index(); $li.removeClass(); $this.addClass('active');

  • js移动端事件基础及常用事件库详解

    一.事件基础 PC:click.mouseover.mouseout.mouseenter.mouseleave.mousemove.mousedown.mouseup.mousewheel.keydown.keyup.load.scroll.blur.focus.change... 移动端:click(单击).load.scroll.blur.focus.change.input(代替keyup.keydown)...TOUCH事件模型(处理单手指操作).GESTURE事件模型(处理多手指操作

  • 基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)

    最近由于公司项目需要图片查看器,网上搜了一圈,感觉资料很少,所以决定基于百度的touch.js手势库+zepto.js自己写了一个小插件,实现了左右滑动,双指缩放,双击缩放功能,基本使用还行,但是有时候还是不太顺畅,后续会慢慢完善:写的不好的地方望各位能够给出好的建议,谢谢! 源码地址:https://github.com/GLwen/molong_photoSwipe.git 演示:http://runjs.cn/detail/iceaaogh molong.css *{padding:0;m

  • 基于zepto.js简单实现上传图片

    效果如下: html: <div class="otherPic"> <div id="showOtherImage"></div> <span class="pull-left position_relative" id="openIdCardImg"> <span class="icon color-blue addPic"></spa

随机推荐