基于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 相关文章推荐
js下将字符串当函数执行的方法
Jul 13 Javascript
百度地图api应用标注地理位置信息(js版)
Feb 01 Javascript
JQuery的$命名冲突详细解析
Dec 28 Javascript
JQuery实现表格动态增加行并对新行添加事件
Jul 30 Javascript
jQuery添加/改变/移除CSS类及判断是否已经存在CSS
Aug 20 Javascript
javascript继承机制实例详解
Nov 20 Javascript
javascript基本类型详解
Nov 28 Javascript
详解JavaScript中的表单验证
Jun 16 Javascript
JavaScript事件代理和委托详解
Apr 08 Javascript
在nginx上部署vue项目(history模式)的方法
Dec 28 Javascript
微信小程序实现topBar底部选择栏效果
Jul 20 Javascript
vue+Vue Router多级侧导航切换路由(页面)的实现代码
Dec 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
php 网页播放器用来播放在线视频的代码(自动判断并选择视频文件类型)
2010/06/03 PHP
使用PHP 5.0创建图形的巧妙方法
2010/10/12 PHP
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
php mysql获取表字段名称和字段信息的三种方法
2016/11/13 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
URL编码转换,escape() encodeURI() encodeURIComponent()
2006/12/27 Javascript
为JavaScript添加重载函数的辅助方法
2010/07/04 Javascript
IE浏览器不支持getElementsByClassName的解决方法
2014/08/27 Javascript
jquery根据锚点offset值实现动画切换
2014/09/11 Javascript
深入理解JavaScript系列(19):求值策略(Evaluation strategy)详解
2015/03/05 Javascript
javascript实现省市区三级联动下拉框菜单
2015/11/17 Javascript
jQuery on()方法绑定动态元素的点击事件无响应的解决办法
2016/07/07 Javascript
原生JS实现首页进度加载动画
2016/09/14 Javascript
JavaScript正则获取地址栏中参数的方法
2017/03/02 Javascript
Node学习记录之cluster模块
2017/05/31 Javascript
label+input实现按钮开关切换效果的实例
2017/08/16 Javascript
JavaScript中重名的函数与对象示例详析
2017/09/28 Javascript
基于Vue实现图书管理功能
2017/10/17 Javascript
Vue 项目部署到服务器的问题解决方法
2017/12/05 Javascript
10行代码实现微信小程序滑动tab切换
2018/12/28 Javascript
Node.js中Koa2在控制台输出请求日志的方法示例
2019/05/02 Javascript
nuxt引入组件和公共样式的操作
2020/11/05 Javascript
使用python实现拉钩网上的FizzBuzzWhizz问题示例
2014/05/05 Python
详解DeBug Python神级工具PySnooper
2019/07/03 Python
python使用ctypes调用扩展模块的实例方法
2020/01/28 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
python从PDF中提取数据的示例
2020/10/30 Python
CSS超出文本指定宽度用省略号代替和文本不换行
2016/05/05 HTML / CSS
室内设计自我鉴定
2013/10/15 职场文书
九年级语文教学反思
2014/02/04 职场文书
《听鱼说话》教学反思
2014/02/15 职场文书
保险公司早会主持词
2014/03/22 职场文书
公司开会通知
2015/04/20 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
MybatisPlus代码生成器的使用方法详解
2021/06/13 Java/Android
python实现商品进销存管理系统
2022/05/30 Python