zoukankan      html  css  js  c++  java
  • 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事件就可完成图片裁切功能。

  • 相关阅读:
    01-面向对象
    12-期末作业
    11-Linux-vim /bash
    组播地址
    rip
    华为hcnp r&s考试一共有三门,R&S-IERS,R&S-IENP,R&S-IEEP

    spring注解开发
    yml和properties的加载顺序和区别
    @ImportResource
  • 原文地址:https://www.cnblogs.com/pomelott/p/10453552.html
Copyright © 2011-2022 走看看