Permalink
Browse files

support doubleTap/singleTap for #254

  • Loading branch information...
1 parent 0d477c7 commit dbbd5011b6c080bdca17c6de6c2d6902ef1c596c @yiminghe yiminghe committed Nov 8, 2012
View
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>The source code</title>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+ <style type="text/css">
+ .highlight { display: block; background-color: #ddd; }
+ </style>
+ <script type="text/javascript">
+ function highlight() {
+ document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+ }
+ </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+ <pre class="prettyprint lang-js"><span id='global-property-'>/**
+</span> * @ignore
+ * gesture swipe inspired by sencha touch
+ * @author yiminghe@gmail.com
+ */
+KISSY.add('event/dom/touch/swipe', function (S, eventHandleMap, Event) {
+
+ var event = 'swipe';
+
+ var MAX_DURATION = 1000,
+ MAX_OFFSET = 35,
+ MIN_DISTANCE = 50;
+
+ function Swipe() {
+ this.event = event;
+ }
+
+ Swipe.prototype = {
+
+ onTouchStart: function (e) {
+ var touches = e.touches, touch;
+ // single touch(mouse)down/up
+ if (touches.length &gt; 1) {
+ return false;
+ }
+ touch = touches[0];
+ this.startTime = e.timeStamp;
+
+ this.isHorizontal = 1;
+ this.isVertical = 1;
+
+ this.startX = touch.pageX;
+ this.startY = touch.pageY;
+
+ if (e.type.indexOf('mouse') != -1) {
+ e.preventDefault();
+ }
+ },
+
+ onTouchMove: function (e) {
+ var touches = e.changedTouches,
+ touch = touches[0],
+ x = touch.pageX,
+ y = touch.pageY,
+ absDeltaX = Math.abs(x - this.startX),
+ absDeltaY = Math.abs(y - this.startY),
+ time = e.timeStamp;
+
+ if (time - this.startTime &gt; MAX_DURATION) {
+ return false;
+ }
+
+ if (this.isVertical &amp;&amp; absDeltaX &gt; MAX_OFFSET) {
+ this.isVertical = 0;
+ }
+
+ if (this.isHorizontal &amp;&amp; absDeltaY &gt; MAX_OFFSET) {
+ this.isHorizontal = 0;
+ }
+
+ if (!this.isHorizontal &amp;&amp; !this.isVertical) {
+ return false;
+ }
+
+ },
+
+ onTouchEnd: function (e) {
+ if (this.onTouchMove(e) === false) {
+ return false;
+ }
+
+ var touches = e.changedTouches,
+ touch = touches[0],
+ x = touch.pageX,
+ y = touch.pageY,
+ deltaX = x - this.startX,
+ deltaY = y - this.startY,
+ absDeltaX = Math.abs(deltaX),
+ absDeltaY = Math.abs(deltaY),
+ distance,
+ direction;
+
+ if (this.isVertical &amp;&amp; absDeltaY &lt; MIN_DISTANCE) {
+ this.isVertical = 0;
+ }
+
+ if (this.isHorizontal &amp;&amp; absDeltaX &lt; MIN_DISTANCE) {
+ this.isHorizontal = 0;
+ }
+
+ if (this.isHorizontal) {
+ direction = deltaX &lt; 0 ? 'left' : 'right';
+ distance = absDeltaX;
+ } else if (this.isVertical) {
+ direction = deltaY &lt; 0 ? 'up' : 'down';
+ distance = absDeltaY;
+ } else {
+ return false;
+ }
+
+ Event.fire(e.target, this.event, {
+<span id='KISSY-Event-DOMEventObject-property-touch'> /**
+</span> *
+ * native touch property **only for event swipe**.
+ *
+ * @property touch
+ * @member KISSY.Event.DOMEventObject
+ */
+ touch: touch,
+<span id='KISSY-Event-DOMEventObject-property-direction'> /**
+</span> *
+ * direction property **only for event swipe**.
+ *
+ * can be one of 'up' 'down' 'left' 'right'
+ * @property {String} direction
+ * @member KISSY.Event.DOMEventObject
+ */
+ direction: direction,
+<span id='KISSY-Event-DOMEventObject-property-distance'> /**
+</span> *
+ * distance property **only for event swipe**.
+ *
+ * the distance swipe gesture costs
+ * @property {Number} distance
+ * @member KISSY.Event.DOMEventObject
+ */
+ distance: distance,
+<span id='KISSY-Event-DOMEventObject-property-duration'> /**
+</span> *
+ * duration property **only for event swipe**.
+ *
+ * the duration swipe gesture costs
+ * @property {Number} duration
+ * @member KISSY.Event.DOMEventObject
+ */
+ duration: e.timeStamp - this.startTime
+ });
+ }
+
+ };
+
+ eventHandleMap[event] = Swipe;
+
+ return Swipe;
+
+}, {
+ requires: ['./handle-map', 'event/dom/base']
+});</pre>
+</body>
+</html>
@@ -0,0 +1,87 @@
+/**
+ * @ignore
+ * gesture single tap double tap
+ * @author yiminghe@gmail.com
+ */
+KISSY.add('event/dom/touch/double-tap',
+ function (S, eventHandleMap, Event, SingleTouch) {
+
+ var SINGLE_TAP = 'singleTap',
+ DOUBLE_TAP = 'doubleTap';
+
+ var MAX_DURATION = 300;
+
+ function DoubleTap() {
+ }
+
+ S.extend(DoubleTap, SingleTouch, {
+
+ onTouchStart: function (e) {
+ if (DoubleTap.superclass.onTouchStart.apply(this, arguments) === false) {
+ return false;
+ }
+ this.startTime = e.timeStamp;
+ if (this.singleTapTimer) {
+ clearTimeout(this.singleTapTimer);
+ this.singleTapTimer = 0;
+ }
+ },
+
+ onTouchMove: function () {
+ return false;
+ },
+
+ onTouchEnd: function (e) {
+ var lastEndTime = this.lastEndTime,
+ time = e.timeStamp,
+ target = e.target,
+ touch = e.changedTouches[0],
+ duration = time - this.startTime;
+ this.lastEndTime = time;
+ // second touch end
+ if (lastEndTime) {
+ // time between current up and last up
+ duration = time - lastEndTime;
+ // a double tap
+ if (duration < MAX_DURATION) {
+ // a new double tap cycle
+ this.lastEndTime = 0;
+
+ Event.fire(target, DOUBLE_TAP, {
+ touch: touch,
+ duration: duration
+ });
+ return;
+ }
+ // else treat as the first tap cycle
+ }
+
+ // time between down and up is long enough
+ // then a singleTap
+ duration = time - this.startTime;
+ if (duration > MAX_DURATION) {
+ Event.fire(target, SINGLE_TAP, {
+ touch: touch,
+ duration: duration
+ })
+ } else {
+ // buffer singleTap
+ // wait for a second tap
+ this.singleTapTimer = setTimeout(function () {
+ Event.fire(target, SINGLE_TAP, {
+ touch: touch,
+ duration: duration
+ });
+ }, MAX_DURATION);
+ }
+
+ }
+ });
+
+ eventHandleMap[SINGLE_TAP] = eventHandleMap[DOUBLE_TAP] = DoubleTap;
+
+ return DoubleTap;
+
+ }, {
+ requires: ['./handle-map', 'event/dom/base', './single-touch']
+ });
@@ -0,0 +1,23 @@
+/**
+ * single touch guard
+ * @author yiminghe@gmail.com
+ */
+KISSY.add('event/dom/touch/single-touch', function (S) {
+
+ function SingleTouch() {
+ }
+
+ SingleTouch.prototype = {
+ onTouchStart: function (e) {
+ var touches = e.touches;
+ // single touch(mouse)down/up
+ if (touches.length > 1) {
+ return false;
+ }
+ },
+ onTouchMove: S.noop,
+ onTouchEnd: S.noop
+ };
+
+ return SingleTouch;
+});
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="apple-touch-fullscreen" content="yes">
+ <meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="apple-touch-fullscreen" content="yes">
+ <script src="../../../../../../../../build/kissy.js"></script>
+ <script src="../../../../../../../log.js"></script>
+</head>
+<body>
+
+<h1>open in ios safari test doubleTap event</h1>
+
+<a href="http://www.g.cn">google</a>
+
+<div id='t' tabindex='0'
+ style='border:1px solid green;
+ width:100px;height:100px;margin:10px'>
+ tttt ttttt ttttt tttttt tttttt
+</div>
+
+<script>
+
+ KISSY.use('event,event/dom/touch', function (S, Event) {
+
+ Event.on('#t', "singleTap doubleTap", function (e) {
+ log(e.type + ' : ' + e.duration);
+ });
+
+ });
+
+</script>
+</body>
+</html>

0 comments on commit dbbd501

Please sign in to comment.