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


Posted in Javascript onMarch 05, 2015

调用方式 :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>

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

Javascript 相关文章推荐
javascript cookie解码函数(兼容ff)
Mar 17 Javascript
有关DOM元素与事件的3个谜题
Nov 11 Javascript
jQuery滚动加载图片效果的实现
Mar 06 Javascript
jQuery函数的等价原生函数代码示例
May 27 Javascript
详细分析JavaScript函数定义
Jul 16 Javascript
微信小程序 数据绑定详解及实例
Oct 25 Javascript
详解JS中的柯里化(currying)
Aug 17 Javascript
微信小程序排坑指南详解
May 23 Javascript
angular 表单验证器验证的同时限制输入的实现
Apr 11 Javascript
微信小程序webview与h5通过postMessage实现实时通讯的实现
Aug 20 Javascript
JavaScript对象原型链原理解析
Jan 22 Javascript
vue-cli3项目打包后自动化部署到服务器的方法
Sep 16 Javascript
基于jQuery实现网页进度显示插件
Mar 04 #Javascript
基于jQuery实现仿淘宝套餐选择插件
Mar 04 #Javascript
js实现类似于add(1)(2)(3)调用方式的方法
Mar 04 #Javascript
jquery 插件实现多行文本框[textarea]自动高度
Mar 04 #Javascript
JavaScript常用脚本汇总(三)
Mar 04 #Javascript
JavaScript常用脚本汇总(二)
Mar 04 #Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
Mar 04 #Javascript
You might like
php4的session功能评述(二)
2006/10/09 PHP
php截取字符串函数分享
2015/02/02 PHP
php实现删除空目录的方法
2015/03/16 PHP
PHP new static 和 new self详解
2017/02/19 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
js console.log打印对像与数组用法详解
2016/01/21 Javascript
js 轮播效果实例分享
2016/12/28 Javascript
Ajax验证用户名或昵称是否已被注册
2017/04/05 Javascript
AngularJS 的$timeout服务示例代码
2017/09/21 Javascript
使用jQuery实现两个div中按钮互换位置的实例代码
2017/09/21 jQuery
基于js中this和event 的区别(详解)
2017/10/24 Javascript
vue2 router 动态传参,多个参数的实例
2017/11/10 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
Python 模块EasyGui详细介绍
2017/02/19 Python
Python生成随机密码的方法
2017/06/16 Python
pyinstaller还原python代码过程图解
2020/01/08 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
2020/01/10 Python
Python 实现使用空值进行赋值 None
2020/03/12 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
2020/06/08 Python
pytorch随机采样操作SubsetRandomSampler()
2020/07/07 Python
深入分析python 排序
2020/08/24 Python
HTML5中的进度条progress元素简介及兼容性处理
2016/06/02 HTML / CSS
床上用品全球在线购物:BeddingInn
2016/12/18 全球购物
Zooplus罗马尼亚:宠物食品和配件
2019/11/02 全球购物
Oracle快照(snapshot)
2015/03/13 面试题
C#笔试题和英文面试题
2013/02/07 面试题
linux面试题参考答案(7)
2012/10/29 面试题
护理专科毕业推荐信
2013/11/10 职场文书
企业元宵节主持词
2014/03/25 职场文书
副总经理岗位职责范本
2014/09/30 职场文书
停车场管理协议书范本
2014/10/08 职场文书
致创业您:正能量激励人心句子(48条)
2019/08/15 职场文书
python 中yaml文件用法大全
2021/07/04 Python
与Windows10相比Windows11有哪些改进?值不值得升级?
2021/11/21 数码科技
MySQL存储过程及语法详解
2022/08/05 MySQL