H5移动端开发基础(四)多指操作、案例-相册

多指操作

// gesturestart:手指触碰元素,屏幕上有两个或两个以上的手指
oBox.addEventListener('gesturestart', function(e){
	// TODO ...
}, false);
// gesturechange:手指触碰元素,屏幕上有两个或两个以上的手指,位置在发生移动
oBox.addEventListener('gesturechange', function(e){
	// TODO ...
	/*
	e.scale:缩放值
	e.rotation:旋转角度
	*/
}, false);
// gestureend:手指离开
oBox.addEventListener('gestureend', function(){
	// TODO ...
});

// 在安卓上是没有gestureXXX事件的
<style type="text/css">
#box{width: 200px; height: 200px;background: red;}
</style>
<div id="box"></div>

旋转

旋转:初始值+差值

document.addEventListener('touchstart', function(e){
	e.preventDefault();
});
var oBox = document.querySelector('#box');
var start = 0;
oBox.addEventListener('gesturestart', function(e){
	start = cssTransform(box, 'rotate');
}, false);
oBox.addEventListener('gesturechange', function(e){
	var disR = e.rotation;
	cssTransform(box, 'rotate', start + disR);
}, false);

缩放

缩放:初始值*差值

document.addEventListener('touchstart', function(e){
	e.preventDefault();
});
var oBox = document.querySelector('#box');
var start = 0;
// 消除缩放时的残影
cssTransform(box, 'translateZ', 0);
oBox.addEventListener('gesturestart', function(e){
	start = cssTransform(box, 'scale');
}, false);
oBox.addEventListener('gesturechange', function(e){
	var disS = e.scale;
	cssTransform(box, 'scale', start*disS);
}, false);

实现安卓多指事件

function gestrue(el, callBack){
	var isGestrue = false;
	var start = {};
	el.addEventListener('touchstart', function(e){
		if(e.touches.length >= 2){
			isGestrue = true;
			start.dis = getDistance(e.touches[0], e.touches[1]);
			start.deg = getAngle(e.touches[0], e.touches[1]);
			if(callBack && callBack.start){
				callBack.start.call(el);
			}
		}
	}, false);
	el.addEventListener('touchmove', function(e){
		if(e.touches.length >= 2 && isGestrue){
			var dis = getDistance(e.touches[0], e.touches[1]);
			e.scale = dis/start.dis;
			var deg = getAngle(e.touches[0], e.touches[1]);
			e.rotation = deg - start.deg;
			if(callBack && callBack.change){
				callBack.change.call(el, e);
			}
		}
	}, false);
	el.addEventListener('touchend', function(e){
		if(isGestrue){
			if(callBack && callBack.end){
				callBack.end.call(el);
			}
		}
		isGestrue = false;
	}, false);

	function getDistance(p1, p2){
		var x = p1.pageX - p2.pageX;
		var y = p1.pageY - p2.pageY;
		return Math.sqrt(x*x + y*y);
	}

	function getAngle(p1, p2){
		var x = p1.pageX - p2.pageX;
		var y = p1.pageY - p2.pageY;
		return Math.atan2(y, x)*180/Math.PI;
	}
}

案例-相册

body{margin: 0;}
html, body{height: 100%;overflow: hidden;}
header{height: 2rem;background: #000;font: .8rem/2rem '宋体';color: #fff;text-align: center;}
#wrap{position: absolute;top: 2rem;bottom:0;left: 0;width: 100%;overflow: hidden;}
#scroll{position: relative;}
#list{overflow: hidden;margin: 0;padding: 0;list-style: none;}
#list li{float: left;width: 7rem;margin: .5rem;min-height: 7rem;border-radius: 5px;background: url(img/loadingImg.gif) no-repeat #ccc center center;}
footer{position: absolute;bottom:-80px;left: 0;width: 100%height:80px;font:.7rem/80px '宋体';text-align: center;width: 100%;transition: .3s opacity;}
#list li canvas{display: block;width: 100%;height: 100%;border-radius: 5px;opacity: 0;transition: .5s}
#bar {position: absolute;right: 0;top: 0;width: 4px;height: 0;background: rgba(0, 0, 0, .8);opacity: 0;transition: .3s opacity;}
#bigImg{position: absolute;left: 0;right: 0;top: 0;width: 100%;height: 100%;background: #ccc;-webkit-transform:scale(0);transform: scale(0);opacity:0;z-index: 3;transition: .3s/* -webkit-transform, .5s opacity*/;}
#clos{float: right;color: #fff;text-decoration: none;}
#canvas{position: absolute;left: 50%;top: 50%;margin: -6rem 0 0 -6rem;width: 12rem;height: 12rem;background: #fff;}
<header>相册</header>
<section id="wrap">
	<div id="scroll">
		<ul id="list"></ul>
		<footer>加载更多...</footer>
	</div>
	<div id="bar"></div>
</section>
<section id="bigImg">
	<header>大图预览<a href="javascript:void(0);" id="clos">关闭</a></header>
	<canvas id="canvas"></canvas>
</section>
<script type="text/javascript" src="js/transform.js"></script>
<script type="text/javascript" src="js/scrollBar.js"></script>
<script type="text/javascript" src="js/tween.js"></script>
<script type="text/javascript" src="js/gestrue.js"></script>
function getImgUrls(){
	var urls = [];
	for(var i=0;i<30;i++){
		urls.push('img/'+(i%16+1)+'.jpg');
	}
	return urls;
}
document.addEventListener('touchstart', function(ev){
	var e = ev || event;
	e.preventDefault();
}, false);
window.onload = function(){
	var wrap = document.querySelector('#wrap');
	var child = wrap.children[0];
	var bar = document.querySelector('#bar');
	var oList = document.querySelector('#list');
	var footer = document.querySelector('footer');
	cssTransform(footer, 'scale', 0);
	var imgs = getImgUrls();
	var length = 12;
	var start = 0;
	var isOver = false;
	var scaleBar = wrap.clientHeight/child.offsetHeight;
	var c = document.querySelector('#canvas');
	var ct = c.getContext('2d');
	var oClos = document.querySelector('#clos');
	var bigImg = document.querySelector('#bigImg');

	cssTransform(footer, 'scale', 0);
	createLi();
	// 开启3D
	cssTransform(footer, 'translateZ', 0.01);
	cssTransform(bar, 'translateZ', 0.01);
	/*
	添加滑屏滚动条
	*/
	var maxScroll = wrap.clientHeight - child.offsetHeight;
	var isLoad = false;
	var footerHeight = footer.offsetHeight;
	moveScroll(wrap, {
		start: function(){
			child.style.transition = 'none';
			var scrollTop = cssTransform(child, 'translateY');
			maxScroll = wrap.clientHeight - child.offsetHeight;
			scaleBar = wrap.clientHeight/child.offsetHeight;
			var barTop = -(scrollTop*scaleBar);
			cssTransform(bar, 'translateY', barTop);
			bar.style.height = wrap.clientHeight * scaleBar + 'px';
			bar.style.opacity = 1;
			if(!isOver && scrollTop <= maxScroll){
				isLoad = true;
			}
		},
		in: function(){
			createImg();
			var scrollTop = cssTransform(child, 'translateY');
			var barTop = -(scrollTop*scaleBar);
			cssTransform(bar, 'translateY', barTop);
			if(!isOver && isLoad){
				var over = maxScroll - scrollTop;
				var scale = over/footerHeight;
				scale = scale>1 ? 1 : scale;
				scale = scale<0 ? 0 : scale;
				cssTransform(footer, 'scale', scale);
			}
		},
		end: function(){
			var scrollTop = cssTransform(child, 'translateY');
			if(!isOver && isLoad && (maxScroll-scrollTop)>=footerHeight){
				console.log('加载新图');
				clearInterval(child.scroll);
				start += length;
				createLi();
				console.log(start);
				bar.style.opacity = 0;
			}
			isLoad = false;					
		},
		over: function() {
              	bar.style.opacity = 0;
          	}
	});
	/*
	创建li
	*/
	function createLi(){
		if(!isOver && start >= imgs.length){
			footer.innerHTML = '没有新图了';
			setTimeout(function(){
				child.style.transition = '.3s';
				cssTransform(child, 'translateY', maxScroll);
				isOver = true;
				footer.style.opacity = 0;
			}, 2000);
			return;
		}
		var end = start + length;
		end = end>imgs.length ? imgs.length : end;
		for(var i=start; i<end;i++){
			var li = document.createElement('li');
			// li.setAttribute('src', imgs[i]);
			li.src = imgs[i];
			li.isLoad = false;
			li.isMove = false;
			// 防止误触
			li.addEventListener('touchstart', function(){
				li.isMove = false;
			});
			li.addEventListener('touchmove', function(){
				li.isMove = true;
			});
			/*
				图片预览
			*/
			li.addEventListener('touchend', function(ev){
				if(this.isMove){
					return;
				}
				var left = this.getBoundingClientRect().left;
                      var top = this.getBoundingClientRect().top;
                      var img = new Image();
                      img.src = this.src;
                      img.onload = function() {
                      	c.width = img.width;
                          c.height = img.height;
                          cssTransform(c, 'scale', 1);
                          cssTransform(c, 'rotate', 0);
                          ct.drawImage(img,0,0,c.width,c.height);
                          bigImg.style.WebkitTransformOrigin = bigImg.style.transformOrigin = left+'px '+top+'px';
                          bigImg.style.opacity = 1;
					cssTransform(bigImg, 'scale', 1);
                      }
			}, false);
			oList.appendChild(li);
		}
		createImg();
		cssTransform(footer, 'scale', 0);
	}
	/*创建图片*/
	function createImg(){
		// var lis = document.querySelectorAll('#list li');
		var lis = oList.getElementsByTagName('li');
		var minTop = wrap.getBoundingClientRect().top;
		var maxTop = minTop + wrap.getBoundingClientRect().height;
		for(var i=0; i<lis.length; i++){
			// 获取到元素在屏幕中的绝对坐标
			var top = lis[i].getBoundingClientRect().top;
			if(!lis[i].isLoad && top>=minTop && top<maxTop){
				lis[i].isLoad = true;
				showImg(lis[i]);
			}
		}
	}
	/*
	展示图片
	*/
	function showImg(li){
		var img = new Image();
		img.src = li.src;
		// li.appendChild(img);
		/*
		加载图片的过程:加载  渲染  
			-- 用canvas(移动端 ==> GPU(显卡)加速)
		*/ 
		img.onload = function(){
			var c = document.createElement('canvas');
			var ctx = c.getContext('2d');
			c.width = img.width;
			c.height = img.height;
			ctx.drawImage(img, 0, 0, c.width, c.height);
			li.appendChild(c);
			setTimeout(function(){
				c.style.opacity = 1;
				/*
				transition在使用的时候,元素没有渲染完是没有效果的
				因此我们加点延迟
				*/
			}, 100);
		}
	}
	oClos.addEventListener('touchend', function(ev){
		cssTransform(bigImg, 'scale', 0);
	}, false);
	gesCanvas();
	function gesCanvas(){
		cssTransform(c, 'translateZ', 0.01);
		var startS = 0;
       var startR = 0;
       gestrue(c, {
           start:function(e) {
               startS = cssTransform(this, 'scale');
               startR = cssTransform(this, 'rotate');
           },
           change:function(e) {
               var disS = e.scale;
               var disR = e.rotation;
               cssTransform(this, 'scale',startS*disS);
               cssTransform(this, 'rotate', startR+disR);
           }
       }); 
	}
}

猜你喜欢

转载自blog.csdn.net/yangwei234/article/details/84943682
今日推荐