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事件就可完成图片裁切功能。

  • 相关阅读:
    如何在iTerm2中配置oh my zsh?
    sublime中格式化jsx文件
    ES6 new syntax of Literal
    ES6 new syntax of Rest and Spread Operators
    How to preview html file in our browser at sublime text?
    ES6 new syntax of Default Function Parameters
    ES6 new syntax of Arrow Function
    七牛云2018春招笔试题
    Spring-使用注解开发(十二)
    Spring-声明式事物(十一)
  • 原文地址:https://www.cnblogs.com/pomelott/p/10453552.html
Copyright © 2011-2022 走看看