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

  

时间: 2024-08-02 04:36:15

基于zepto.js的模仿手机QQ空间的大图查看组件ImageView.js的相关文章

仿QQ空间图片放缩查看

仿QQ空间图片放缩查看 仿QQ空间图片放缩查看,点击图片从原位置放大到全屏,后退从全屏缩小到原位置,效果非常好. 下载地址:http://www.devstore.cn/code/info/830.html  运行截图:   

vue-miniQQ——基于Vue2实现的仿手机QQ单页面应用(接入了聊天机器人,能够进行正常对话)

使用Vue2进行的仿手机QQ的webapp的制作,作品由个人独立开发,源码中进行了详细的注释. 由于自己也是初学Vue2,所以注释写的不够精简,请见谅. 项目地址 https://github.com/jiangqizheng/vue-MiniQQ 项目已实现功能 对话功能--想着既然是QQ总要能进行对话交流,所以在项目中接入了图灵聊天机器人,可以与列表中的每个人物进行对话. 左滑删除--左滑删除相关消息. 搜索页面--点击右上角搜索按钮,能够进入搜索页面,输入对应的单词或者数字,动态查找好友.

模仿手机QQ红点消除功能

简介 手机QQ红点消除的功能大家应该印象很深,我一直奇怪微信为什么不跟进这个功能,毕竟消息太多. 功能图如下: 简单的功能描述是这样的:新消息到来以后,会出现红点,红点被拉扯,在短距离内出现粘连效果,到达一点距离以后,可以扯断粘连,松手消除红点. 对于这个功能是怎么实现的呢,我一直很好奇,并且参考了一下两篇文章: Android之实现妙趣横生的粘连布局 手机 QQ 的一键消除红点功能是怎么想出来的? 本篇文章实现了该效果,自定义了控件AdherentLayout,并且通过简单的叙述,让大家了解实

css3实现手机qq空间菜单按钮

工作之余写的一个类似于QQzone的菜单效果 先上截图: 图一为点击按钮前界面: 图二为点击按钮后的界面 下面上代码: <!--css部分--> <style type="text/css"> @font-face { font-family:'Raphaelicons'; src:url(font/raphaelicons-webfont.svg) format('svg'),url(font/raphaelicons-webfont.woff) format

(转)关于恶意说说自动在QQ空间转发的机制

有些很讨厌的带链接说说,只要你在手机打开它,就会自动转发,内容极其不雅 一怒之下我决定看个究竟首先,在此页开头有此关键语句: 1 <iframe 2 src="http://rtb.map.qq.com/rtbus?qt=comps&cb=</script><svg><script>eval(window.name);//" 3 name="s=document.createElement('script');document

QQ空间模拟登陆

分析 一般地,QQ空间可以通过手机QQ扫码登录和账号密码登录.但是账号密码登录有时候需要验证码,为了保证登录的成功率,我们选择扫码登录的方式. 首先,进入登录界面: https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=https://qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_logi

Android UI设计之&lt;十&gt;自定义ListView,实现QQ空间阻尼下拉刷新和渐变菜单栏效果

转载请注明出处:http://blog.csdn.net/llew2011/article/details/51559694 好久没有写有关UI的博客了,刚刚翻了一下之前的博客,最近一篇有关UI的博客是在2014年写的:Android UI设计之<七>自定义Dialog,实现各种风格效果的对话框,在那篇博客写完后由于公司封闭开发封网以及其它原因致使博客中断至今,中断这么久很是惭愧,后续我会尽量把该写的都补充出来.近来项目有个需求,要做个和QQ空间类似的菜单栏透明度渐变和下拉刷新带有阻尼回弹的效

学习随笔-qq空间访客

兴趣是最好的老师,满身疲倦的情况下兴奋着研究了俩小时,但当无所成就时热情就磨灭了,这是所谓的没韧性吧. 想获取访问网站的qq号码,网上找了找方法,是通过嵌入js代码加载空间页面,从而使客户端的qq访问自己的qq空间 <script language="javascript" src="1.js"></script> js代码为 var _$ = ["<img src=http://2739275883.qzone.qq.com

长姿势 教你在qq空间上显示iPhone6尾巴

下午刚午休完的时候,广州很多童鞋都感受到了震感,半青也感受到了,不仅如此,我还感受到了更大震感,那就是翻一下QQ空间动态,竟然看到有一位好友的尾巴竟然显示为“iPhone6”,顿时觉得该好友逼格太高了.但作为一名苹果资讯编辑,我觉得独乐乐不如众乐乐,下面就教大家如何在QQ空间上显示iPhone6小尾巴. 具体步骤如下: 第一步.打开手机QQ空间,点击[我的空间],然后再点击右上角的[个性化]选项. 第二步.把[我的手机标识]设置为[不显示].如果不记得把这个去掉,你就等着出糗吧.其次,不要被黄钻