超级小的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[].pageX+evt.touch[].pageX)/);
},
然后根据这个坐标和图片的坐标计算图片缩放的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{width:100%;height:100%;}
.view_page{width:100%;height:100%;max-width:640px;position:relative;margin:0 auto;}
.small_map_box{width:100%;}
.small_map_box img{width:100%;display:block;}
.big_map_box{position:absolute;left:0;top:0;width:100%;height:100%;background:rgba(0, 0, 0, 1);max-width: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;width: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="data:images/map_small.jpg" class="small_map" id="small_map" alt="">
</div>
<div class="big_map_box">
<div id="result">fewfew</div>
<img src="data: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
//\b是单词的边界
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(/\b\w+\b/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事件区分开来
超级小的web手势库AlloyFinger的更多相关文章
- 超级小的web手势库AlloyFinger发布
简介 针对多点触控设备编程的Web手势组件,快速帮助你的web程序增加手势支持,也不用再担心click 300ms的延迟了.拥有两个版本,无依赖的独立版和react版本.除了Dom对象,也可监听Can ...
- 超小Web手势库AlloyFinger原理
目前AlloyFinger作为腾讯手机QQ web手势解决方案,在各大项目中都发挥着作用. 感兴趣的同学可以去Github看看:https://github.com/AlloyTeam/AlloyFi ...
- 超小Web手势库AlloyFinger原理(转载)
目前AlloyFinger作为腾讯手机QQ web手势解决方案,在各大项目中都发挥着作用. 感兴趣的同学可以去Github看看: https://github.com/AlloyTeam/AlloyF ...
- vue在移动端使用alloyfinger手势库操作图片拖拽、缩放
最近开发一个活动需要在手机上给上传的头像加上边框.装饰,需要拖拽.手势缩放边框下的头像图片,因为是vue项目,开始尝试了vue-drag-resize这个组件,对图片拖拽支持很完美,但是无法手势缩放, ...
- 强悍的javascript手势库
/** * Toucher * git:https://github.com/cometwo/Toucher-1 */ "use strict"; (function (root, ...
- 移动端手势库hammerJS 2.0.4官方文档翻译
hammerJS是一个优秀的.轻量级的触屏设备手势库,现在已经更新到2.04版本,跟1.0版本有点天壤地别了,毕竟改写了事件名并新增了许多方法,允许同时监听多个手势.自定义识别器,也可以识别滑动方向. ...
- 实现一个javascript手势库 -- base-gesture.js
现在移动端这么普及呢,我们在手机上可以操作更多了.对于网页来说实现一些丰富的操作感觉也是非常有必要的,对吧(如果你仅仅需要click,,那就当我没说咯...)~~比如实现上下,左右滑动,点击之类的,加 ...
- 一套代码小程序&Web&Native运行的探索05——snabbdom
接上文:一套代码小程序&Web&Native运行的探索04——数据更新 对应Git代码地址请见:https://github.com/yexiaochai/wxdemo/tree/ma ...
- 一套代码小程序&Web&Native运行的探索03——处理模板及属性
接上文:一套代码小程序&Web&Native运行的探索02 对应Git代码地址请见:https://github.com/yexiaochai/wxdemo/tree/master/m ...
随机推荐
- 网络配置vlan
1. # This file describes the network interfaces available on your system # and how to activate them. ...
- 《FPGA全程进阶---实战演练》第二章之硬件平台的搭建
学习FPGA,多多少少应该要懂得硬件电路的设计,这样不单单增加了自己的技能,而且还能够对FPGA的硬件实现有更好的了解. 1 模块划分 对于一个基本的FPGA硬件平台,常用的几个电路部分:(1)电源电 ...
- 关于只能上QQ而其他电脑软件(IE/优酷/腾讯视频...)不能联网的解决
1.应该是Winsock协议配置有问题,所以进行一下重置工作. 开始-cmd-输入netsh winsock reset命令来重置Winsock目录重新初始化网络环境来恢复网络畅通-重启电脑才能生效 ...
- 用C语言显示汉字的演示程序
汉字是方块字,宽高相等的汉字库在嵌入式领域有着广泛的应用,且其解析也相对来说是比较简单的.汉字在汉字库中的索引一般会遵循GB2312/GBK编码规则,GB2312/GBK规定汉字编码由2个字节组成,其 ...
- PID控制器的应用:控制网络爬虫抓取速度
一.初识PID控制器 冬天乡下人喜欢烤火取暖,常见的情形就是四人围着麻将桌,桌底放一盆碳火.有人觉得火不够大,那加点木炭吧,还不够,再加点.片刻之后,又觉得火太大,脚都快被烤熟了,那就取出一些木碳…… ...
- 【Java面试题】3 Java的"=="和equals方法究竟有什么区别?简单解释,很清楚
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符. 如果一个变量指向的数据是对象类型的 ...
- Nginx配置PATHINFO隐藏index.php
1.网络来源:http://www.shouce.ren/post/view/id/1529 server { listen 80; default_type text/ ...
- Digest Authentication 摘要认证
“摘要”式认证( Digest authentication)是一个简单的认证机制,最初是为HTTP协议开发的,因而也常叫做HTTP摘要,在RFC2671中描述.其身份验证机制很简单,它采用杂凑式(h ...
- css两列等高布局
布局方案 等高布局有几种不同的方法,但目前为止我认为浏览器兼容最好最简便的应该是padding补偿法.首先把列的padding-bottom设为一个足够大的值,再把列的margin-bottom设一个 ...
- when an event of selector will be fired
OP_READ Operation-set bit for read operations. Suppose that a selection key's interest set contains ...