1. 程式人生 > >H5移動端開發基礎(四)多指操作、案例-相簿

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'