zoukankan      html  css  js  c++  java
  • 超级小的web手势库AlloyFinger

    针对多点触控设备编程的Web手势组件,快速帮助你的web程序增加手势支持,也不用再担心click 300ms的延迟了。拥有两个版本,无依赖的独立版和react版本。除了Dom对象,也可监听Canvas内元素的手势(需要Canvas引擎内置对象支持addEventListener绑定touch相关事件)。

    据不完全统计,目前AlloyFinger服务于:兴趣部落、QQ群、QQ动漫、腾讯学院、TEDxTencent、 AlloyTeam、腾讯CDC等多个部门、团队和项目。

    功能清单

    极小的文件大小

    简洁的API设计

    优秀的性能

    丰富的手势支持

    双版本(react和独立版)

    支持pinch缩放

    支持rotate旋转

    支持pressMove拖拽

    支持doubleTap双击

    支持swipe滑动

    支持longTap长按

    支持tap按

    支持singleTap单击

    快速上手

    独立版使用方式:

    //element为需要监听手势的dom对象
    new AlloyFinger(element, {
        pointStart: function () {
            //手指触摸屏幕触发
        },
        multipointStart: function () {
            //一个手指以上触摸屏幕触发
        },
        rotate: function (evt) {
            //evt.angle代表两个手指旋转的角度
            console.log(evt.angle);
        },
        pinch: function (evt) {
            //evt.scale代表两个手指缩放的比例
            console.log(evt.scale);
        },
        multipointEnd: function () {
            //当手指离开,屏幕只剩一个手指或零个手指触发
        },
        pressMove: function (evt) {
            //evt.deltaX和evt.deltaY代表在屏幕上移动的距离
            console.log(evt.deltaX);
            console.log(evt.deltaY);
        },
        tap: function (evt) {
            //点按触发
        },
        doubleTap: function (evt) {
            //双击屏幕触发
        },
        longTap: function (evt) {
            //长按屏幕750ms触发
        },
        swipe: function (evt) {
            //evt.direction代表滑动的方向
            console.log("swipe" + evt.direction);
        },
        singleTap: function (evt) {
            //单击
        }
    });

    官网DEMO

    http://alloyteam.github.io/AlloyFinger/

    1.必须跟transformjs一起用吗?

    不必须。也可以在事件回调里根据evt携带的信息使用js去操作CSS3。但是一起用,会让代码更简洁。

    2.pinch、rotate事件怎么在chrome浏览器调试的?

    一般用真机调试,但是也可以使用chrome浏览器,传送门 http://www.html5rocks.com/en/mobile/touch/#toc-touchdev

    3.缩放的origin点设置,这里是想手在图片哪个区域操作就设置哪里为origin进行缩放?

    自己去计算就是两个手指的连线的中点的坐标,

    比如中点X:

      pinch: function (evt) { 
            console.log((evt.touch[0].pageX+evt.touch[1].pageX)/2);
        },

    然后根据这个坐标和图片的坐标计算图片缩放的origin

    4.拖拽位置、缩放大小是否可以限制(始终在屏幕内显示,避免出现缩到很小看不到的情况)

    这个不应该有 AlloyFinger 控制。而应该由你的逻辑去控制

    https://github.com/AlloyTeam/AlloyFinger

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>AlloyFinger</title>
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <link rel="stylesheet" href="style/reset.css">
        <link rel="stylesheet" href="style/main.css">
        <script type="text/javascript" src="script/jquery-1.9.1.min.js"></script>
        <style>
        html, body{100%;height:100%;}
        .view_page{100%;height:100%;max-640px;position:relative;margin:0 auto;}
        .small_map_box{100%;}
        .small_map_box img{100%;display:block;}
        .big_map_box{position:absolute;left:0;top:0;100%;height:100%;background:rgba(0, 0, 0, 1);max-640px;z-index:100;display:none;
            -webkit-transform-origin:50% 20%;transform-origin:50% 20%;}
        .big_map_box.active{
            -webkit-animation:globalSca 0.4s ease both;
            -moz-animation:globalSca 0.4s ease both;
            -ms-animation:globalSca 0.4s ease both;
            animation:globalSca 0.4s ease both;
        }
        @-webkit-keyframes globalSca{
            0%{-webkit-transform:scale(0);background:rgba(0, 0, 0, 0);}
            100%{-webkit-transform:scale(1);background:rgba(0, 0, 0, 1);}
        }
        @-moz-keyframes globalSca{
            0%{-moz-transform:scale(0);background:rgba(0, 0, 0, 0);}
            100%{-moz-transform:scale(1);background:rgba(0, 0, 0, 1);}
        }
        @-ms-keyframes globalSca{
            0%{-ms-transform:scale(0);background:rgba(0, 0, 0, 0);}
            100%{-ms-transform:scale(1);background:rgba(0, 0, 0, 1);}
        }
        @keyframes globalSca{
            0%{transform:scale(0);background:rgba(0, 0, 0, 0);}
            100%{transform:scale(1);background:rgba(0, 0, 0, 1);}
        }
        .big_map_box.active2{
            -webkit-animation:globalScatoZero 0.4s ease both;
            -moz-animation:globalScatoZero 0.4s ease both;
            -ms-animation:globalScatoZero 0.4s ease both;
            animation:globalScatoZero 0.4s ease both;
        }
        @-webkit-keyframes globalScatoZero{
            0%{-webkit-transform:scale(1)}
            100%{-webkit-transform:scale(1);opacity:0;}
        }
        @-moz-keyframes globalScatoZero{
            0%{-moz-transform:scale(1)}
            100%{-moz-transform:scale(1);opacity:0;}
        }
        @-ms-keyframes globalScatoZero{
            0%{-ms-transform:scale(1)}
            100%{-ms-transform:scale(1);opacity:0;}
        }
        @keyframes globalScatoZero{
            0%{transform:scale(1)}
            100%{transform:scale(1);opacity:0;}
        }
        /*@-webkit-keyframes mymove{
            0%   {-webkit-transform:scale(0);}
            100%   {-webkit-transform:scale(1);}
        }
    
        @keyframes mymove{
            0%   {transform:scale(0);}
            100%   {transform:scale(1);}
        }*/
    
        .big_map_box img{position:absolute;100%;left:0;top:50%;}
        #result{position:absolute;left:0;top:0;color:#fff;}
        </style>
    </head>
    <body>
        <div class="view_page">
            <div class="small_map_box" id="small_map_box">
                <img src="images/map_small.jpg" class="small_map" id="small_map" alt="">
            </div>
            <div class="big_map_box">
                <div id="result">fewfew</div>
                <img src="images/map_big.jpg" class="big_map" id="big_map" alt="">
            </div> 
        </div>
    </body>
    </html>
    <script type="text/javascript" src="AlloyFinger-master/alloy_finger.js"></script>
    <script type="text/javascript" src="AlloyFinger-master/asset/transform.js"></script>
    <!-- <script type="text/javascript" src="AlloyFinger-master/asset/image_loaded.js"></script> -->
    <script type="text/javascript" src="AlloyFinger-master/asset/to.js"></script>
    <script type="text/javascript">
    !(function(){
        var winW = window.innerWidth;
        var smallmap = document.getElementById("small_map_box");
        var bigmap = document.getElementById("big_map");
        smallmap.addEventListener("touchstart", function(){
            smallmap.addEventListener("touchend", touchEnd, false);
        }, false);
    
        smallmap.addEventListener("touchmove", function(){
            smallmap.removeEventListener("touchend", touchEnd, false);
        }, false);
    
        smallmap.addEventListener("touchend", touchEnd, false);
    
        function touchEnd(){
            $(".big_map_box").css({"display": "block"}).removeClass("active2").addClass("active");
            bigmap.style.marginTop = -Math.round((winW * 1.0533333333))/ 2 + "px";
            bigmap.style.transform = "perspective(500px) matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)";
            bigmap.style.webkitTransform = "perspective(500px) matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)";
        }
        Transform(bigmap);
        var initScale = 1;
        var handlerMap = new AlloyFinger(bigmap, {
            //一个手指以上触摸屏幕触发
            multipointStart: function () {
                initScale = this.scaleX;
            },
    
            //当手指离开,屏幕只剩一个手指或零个手指触发
            multipointEnd: function (evt) {
                // bigmap.onclick = function(){
                //     $(".big_map_box").removeClass("active");
                // }
    
                // 缩放小于1的动画
                if(this.scaleX < 1){
                    new To(this, "scaleX", 1, 300);         // 绽放归位
                    new To(this, "scaleY", 1, 300);         // 绽放归位
                    new To(this, "translateX", 0, 300);     // 位移归位
                    new To(this, "translateY", 0, 300);     // 位移归位
                    new To(this, "rotateZ", 0, 300);        // 旋转归位
                    // 自己写的动画
                    // var that = this;
                    // this.scaleX = this.scaleY = 1;
                    // this.translateX = 0;
                    // this.translateY = 0;
                    // this.style.transition = "all 0.3s";
                    // setTimeout(function(){
                    //     this.style.transition = "0ms";
                    // }.bind(this), 300);
                }
                // 限制最大的尺寸
                if(this.scaleX > 3){
                    // this.scaleX = this.scaleY = 3;
                    new To(this, "scaleX", 3, 200);         // 绽放归位
                    new To(this, "scaleY", 3, 200);         // 绽放归位
                }
            },
    
            // 旋转
            // rotate: function (evt) {
            //     evt.preventDefault();
            //     //evt.angle代表两个手指旋转的角度
            //     this.rotateZ += evt.angle;
            // },
    
            // 双指缩放
            pinch: function (evt) {
                handlerMap.isDoubleTap = true;
                this.scaleX = this.scaleY = initScale * evt.zoom;
                evt.preventDefault();
    
            },
            // 双击放大
            // doubleTap: function () {
            //     handlerMap.isDoubleTap = true;
            //     if(this.scaleX === 1){
            //         new To(this, "scaleX", 3, 300);
            //         new To(this, "scaleY", 3, 300);
            //     }else if(this.scaleX === 3){
            //         new To(this, "scaleX", 1, 300);
            //         new To(this, "scaleY", 1, 300);
            //         new To(this, "translateX", 0, 300);     // 位移归位
            //         new To(this, "translateY", 0, 300);     // 位移归位
            //     }
            //     /*else if(this.scaleX > 2){
            //         new To(this, "scaleX", 2, 300);
            //         new To(this, "scaleY", 2, 300);
            //     }*/
            // },
            singleTap: function (evt) {
                if(!handlerMap.isDoubleTap){
                    $(".big_map_box").removeClass("active").addClass("active2");
                    setTimeout(function(){
                        $(".big_map_box").css({"display":"none"});
                    },400)
                }
            },
    
            // 移动
            pressMove: function (evt) {
                // 取消单击事件
    
                handlerMap.isDoubleTap = true;
                this.translateX += evt.deltaX;
                this.translateY += evt.deltaY;
    
                // 边界判断. 不让划出屏幕内
                if(this.scaleX === 1){
                    if(this.translateX !== 0){
                        // this.scaleX = this.scaleY = 3;
                        new To(this, "translateX", 0, 200);         // 绽放归位
                    }
                    this.translateY = 0;
                }
                evt.preventDefault();
            }
        })    
      
    
    }());
    
    function classList(e){
        //CSSClassList是一个模拟DOMTokenList的javascript类
        function CSSClassList(e){        
            //系统偷偷替我们做了:
            //var this = new Object();
            this.e = e;
        }   
    
        //contains方法
        CSSClassList.prototype.contains = function(c){
    
            //权威指南的方法
            //检查c是否是合法的类名
            if(c.length === 0 || c.indexOf(" ") != -1){
                throw new Error("invalid class name:'" + c + "'");
            }
            //首先是常规检查
            var classes = this.e.className;
            if(!classes) return false;          //e不含有类名
            if(classes === c) return true;      //e有一个完全匹配的类名
    
            //否则,把c自身看做一个单词,利用正则表达式搜索c
            //是单词的边界
            return classes.search("\b" + c + "\b") != -1;
    
    
            //网上正则方法
            /*var classname = this.e.className, reg = new RegExp("\b" + c + "\b");
            return reg.test(classname);*/
            
        }
    
        //add()方法
        CSSClassList.prototype.add = function(c){
            if(this.contains(c)) return;            //如果存在,则不添加
            var classes = this.e.className;
    
            //判断存在class与class类里最后一个类名没有空白格
            if(classes && classes[classes.length-1] != " "){
                c = " " + c;        
                this.e.className += c;          //将c添加到className中
            }
        }
    
        //remove()方法
        CSSClassList.prototype.remove = function(c){
            //检查c是否是合法的类名
            if(c.length === 0 || c.indexOf(" ") != -1){
                throw new Error("invalid class name:'" + c + "'");
            }
            //将所有作为单词的c和多余的尾随空格全部删除
            var pattern = new RegExp("\b" + c + "\b\s*","g");
            this.e.className = this.e.className.replace(pattern,"")
        }
    
        //toggle()方法,添加返回true,删除返回false
        CSSClassList.prototype.toggle = function(c){
            if(this.contains(c)){       //如果e.className包含c
                this.remove(c);         //删除它
                return false;
            }else{
                this.add(c);            //否则,添加它
                return true;
            }
        }
    
        //返回e.className本身
        CSSClassList.prototype.toString = function(){
            return this.e.className;
        };
    
        /*//返回在e.className中的类名 (CSSClassList原生中没有toArray方法)
        CSSClassList.prototype.toArray = function(){
            return this.e.className.match(/w+/g) || {};
        }*/
    
        if(e.classList){
            return e.classList;             //如果classList存在,则返回它
        }else{
            return new CSSClassList(e);     //否则就创建一个
        }
    }
    </script>
    

      

    有几个问题没有解决

    1.IOS图片scale放大模糊问题

    2.doubleTap与pinch触摸问题, 事件冲突

    3.禁止双指放大doubleTap事件, 和在pinch上"handlerMap.isDoubleTap = true;" 来阻止singleTap事件区分开来

  • 相关阅读:
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 88怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 81.0怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 40怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 24.0怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 21.0怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下驱动器试运行提示过速度保护怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下驱动器如何执行绝对值清零
    倍福TwinCAT(贝福Beckhoff)基础教程 松下绝对值驱动器如何做初始化设置
    倍福TwinCAT(贝福Beckhoff)基础教程 松下官方软件开启报错伺服未就绪怎么办
    JAVA Eclipse 启动 Eclipse 弹出“Failed to load the JNI shared library jvm_dll”怎么办
  • 原文地址:https://www.cnblogs.com/alantao/p/7867169.html
Copyright © 2011-2022 走看看