基于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 相关文章推荐
JQuery 操作select标签实现代码
May 14 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
Dec 30 Javascript
localResizeIMG先压缩后使用ajax无刷新上传(移动端)
Aug 11 Javascript
基于jQuery实现select下拉选择可输入附源码下载
Feb 03 Javascript
BootStrap 智能表单实战系列(五) 表单依赖插件处理
Jun 13 Javascript
原生JS实现匀速图片轮播动画
Oct 18 Javascript
ajax分页效果(bootstrap模态框)
Jan 23 Javascript
JavaScript省市级联下拉菜单实例
Feb 14 Javascript
JS验证全角与半角及相互转化的介绍
May 18 Javascript
深入理解Vue.js源码之事件机制
Sep 27 Javascript
Vue组件之自定义事件的功能图解
Feb 01 Javascript
微信小程序实现上拉加载功能
Nov 20 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
ThinkPHP之foreach标签使用概述
2014/06/30 PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
2016/05/04 PHP
zend framework重定向方法小结
2016/05/28 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
2016/09/23 PHP
PHP中quotemeta()函数的用法讲解
2019/04/04 PHP
IE6下通过a标签点击切换图片的问题
2010/11/14 Javascript
使用Sticky组件实现带sticky效果的tab导航和滚动导航的方法
2016/03/22 Javascript
AngularJS学习笔记之依赖注入详解
2016/05/16 Javascript
JavaScript定义全局对象的方法示例
2017/01/12 Javascript
详解在Angularjs中ui-sref和$state.go如何传递参数
2017/04/24 Javascript
jQuery中元素选择器(element)简单用法示例
2018/05/14 jQuery
Node.JS枚举统计当前文件夹和子目录下所有代码文件行数
2019/08/23 Javascript
Vue项目接入Paypal实现示例详解
2020/06/04 Javascript
小程序角标的添加及绑定购物车数量进行实时更新的实现代码
2020/12/07 Javascript
[02:58]献给西雅图的情书_高清
2014/05/29 DOTA
Python中函数的用法实例教程
2014/09/08 Python
在Django框架中编写Context处理器的方法
2015/07/20 Python
单链表反转python实现代码示例
2018/02/08 Python
python实现自动登录后台管理系统
2018/10/18 Python
Numpy截取指定范围内的数据方法
2018/11/14 Python
python使用threading.Condition交替打印两个字符
2019/05/07 Python
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
2019/07/06 Python
python中eval与int的区别浅析
2019/08/11 Python
利用Python脚本实现自动刷网课
2020/02/03 Python
tensorflow实现读取模型中保存的值 tf.train.NewCheckpointReader
2020/02/10 Python
selenium WebDriverWait类等待机制的实现
2020/03/18 Python
Python中Selenium库使用教程详解
2020/07/23 Python
多视角3D逼真HTML5水波动画
2016/03/03 HTML / CSS
欧洲顶级体育电子商务网站:SportsShoes.com
2018/03/27 全球购物
电焊工岗位职责
2014/03/06 职场文书
文秘档案管理岗位职责
2014/03/06 职场文书
中学生勤俭节约倡议书
2015/04/29 职场文书
致运动员加油稿
2015/07/21 职场文书
小学副班长竞选稿
2015/11/21 职场文书
2016小学新学期寄语
2015/12/04 职场文书
python神经网络编程之手写数字识别
2021/05/08 Python