html5手势操作与多指操作封装与Canvas图片裁切实战
当前情况,移动端的开发占比越来越高,单指的拖拽触碰等操作是常规需要。特殊的多指操作与手势操作还需另做处理,而且还涉及到兼容性问题。
// 屏幕上存在两根或两根以上的手指 时触发 仅IOS存在手势事件,安卓不存在需要另外封装 // gesturestart 多指操作触发时 // gesturechange 两根手指发生变化时 // gestureend 两根手指全部抬起时
* 首先是手势操作的参数说明
init:{ el: 要添加事件的元素, start: 摁下时 要操作的事情(gesturestart), change: 手指移动时的回调(gesturechange)function(e){ e.scale//在change时,手指之间的距离 和 start时手指之间距离的比值 e.rotation//在change时和start时 手指旋转角度的差值 }, end: 多指触碰结束的回调(gestureend) }
* 需要用到Math的一个函数: Math.atan2(y, x)
意为:x轴 和 点(x, y)与 (0, 0)连线 逆时针方向形成的夹角
*封装如下:
function gesture(init){ var isGesture = false; var el = init.el; var startDis = 0; var startDeg = 0; //console.log(getDeg({pageX:0,pageY:0},{pageX:-100,pageY:100})); el.addEventListener('touchstart', function(e) { var touch = e.touches;//当前屏幕上的手指列表 if(touch.length >= 2){//当前屏幕有两根以上的手指 isGesture = true; startDis = getDis(touch[0],touch[1]);//start时两根手指之间的距离 startDeg = getDeg(touch[0],touch[1]);//start时,两根手指形成的直线 和 x轴形成一个逆时针的夹角 init.start&&init.start.call(el,e); //this.innerHTML = startDis; } }); el.addEventListener('touchmove', function(e) { var touch = e.touches;//当前屏幕上的手指列表 if(touch.length >= 2&&isGesture){//当前屏幕有两根以上的手指 var nowDis = getDis(touch[0],touch[1]);// move时两根手指之间的距离 var nowDeg = getDeg(touch[0],touch[1]);//move时,两根手指形成的直线 和 轴形成一个逆时针的夹角 e.scale = nowDis/startDis; e.rotation = nowDeg - startDeg; init.change&&init.change.call(el,e); } }); el.addEventListener('touchend', function(e) { if(isGesture){ init.end&&init.end.call(el,e); } isGesture = false; }); function getDis(point,point2){ var x = point2.pageX - point.pageX; var y = point2.pageY - point.pageY; return Math.sqrt(x*x + y*y); } function getDeg(point,point2){ var x = point2.pageX - point.pageX; var y = point2.pageY - point.pageY; return Math.atan2(y,x)*180/Math.PI; } }
缩放卡顿,不流畅的解决方法:
在每次进行手势操作的时候,重新设置缩放值为1
var box = document.querySelector('#box'); var startScale = 1; css(box,"scale",1); gesture({ el:box, start: function(){ startScale = css(box,"scale"); this.style.background = "blue"; }, change: function(e){ // this.innerHTML = "scale:" + e.scale; // this.innerHTML += "<br/>rotate:" + e.rotation; css(this,"scale",e.scale*startScale); }, end: function(){ this.style.background = "red"; } });
图片裁切实战:
需要用到的知识点:
1. getContext('2d')
获取 canvas 2d画布 上下文
2. canvas drawImg(imgDom, x, y, width, height)
此方法必须等到img加载完成之后使用, 用以在画布上绘制参数对应的图片
3. getImageData(x, y, width, height)
获取参数对应区域的图片信息 (必须在服务器环境下使用,且不能跨域)
4.putimageData(ImageDataObj, x, y)
还有许多可选参数,具体可查阅API
用canvas的以上四个知识点加上封装好的gesture事件就可完成图片裁切功能。