Skip to content

Commit 74652f7

Browse files
author
Sebastien Pereira
committed
Add support for touch-action=pan-x|y when Pointer events are generated from Touch Events. Fixes #8. Ref ibm-js/deliteful/issues/225.
1 parent 9d2e666 commit 74652f7

File tree

3 files changed

+195
-9
lines changed

3 files changed

+195
-9
lines changed

handlers/touch.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ define([
6464
// to set a pointer capture on the element, so we must:
6565
// - register the pointer *before* firing the events.
6666
// - update the tracker *before* firing the events.
67-
tracker.register(touch.identifier, touchAction);
67+
tracker.register(touch.identifier, touchAction, touch);
6868
tracker.update(touch, e, touch.target);
6969
// fire pointerover > pointerdown
7070
utils.dispatchEvent(touch.target, createPointer(utils.events.OVER, e, touch, {}));
@@ -85,8 +85,9 @@ define([
8585
if (!tracker.isActive(touch.identifier)) {
8686
return;
8787
}
88+
tracker.updateScroll(touch);
8889
// browser default actions
89-
if (tracker.getTouchAction(touch.identifier) === utils.TouchAction.AUTO) {
90+
if (tracker.isTouchActionEnforced(touch.identifier)) {
9091
var lastNativeEventType = tracker.getTouchEvent(touch.identifier).type;
9192
switch (lastNativeEventType) {
9293
case TouchEvents.touchstart:
@@ -154,7 +155,7 @@ define([
154155
// in that case we use the current touch.target.
155156
var elementFromPoint = elementFromTouch(touch) || touch.target;
156157
var touchTarget = tracker.identifyTouchTarget(touch.identifier, elementFromPoint);
157-
if (tracker.getTouchAction(touch.identifier) === utils.TouchAction.AUTO) {
158+
if (tracker.isTouchActionEnforced(touch.identifier)) {
158159
// default action handled by user agent
159160
switch (lastNativeEventType) {
160161
case TouchEvents.touchmove:

handlers/touchTracker.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,36 @@
11
define([
2-
], function () {
2+
"./utils"
3+
], function (utils) {
34
"use strict";
4-
5-
var TouchInfo = function (touchAction) {
5+
6+
var TouchInfo = function (touchAction, pageX, pageY) {
67
this.touchAction = touchAction;
78
this.lastNativeEvent = null; // undefined
89
this.lastTouch = null; // undefined
910
this.capturedTarget = null; // undefined, rename capturedTarget
1011
this.lastTargetElement = null;
12+
this.firstMove = {
13+
startX: pageX,
14+
startY: pageY
15+
};
16+
this.enforceTouchAction = (touchAction === utils.TouchAction.AUTO);
1117
};
1218

1319
// touchId of the primary pointer, or -1 if no primary pointer set.
1420
var primaryTouchId = -1,
15-
t = {};
21+
t = {},
22+
canScroll = function (a1, b1, a2, b2) {
23+
return Math.abs(a2 - a1) / Math.abs(b2 - b1) > 0.7;
24+
};
1625

1726
return {
1827

19-
register: function (touchId, touchAction) {
28+
register: function (touchId, touchAction, touch) {
2029
// the first touch to register becomes the primary pointer
2130
if (primaryTouchId === -1) {
2231
primaryTouchId = touchId;
2332
}
24-
t[touchId] = new TouchInfo(touchAction);
33+
t[touchId] = new TouchInfo(touchAction, touch.pageX, touch.pageY);
2534
},
2635

2736
unregister: function (touchId) {
@@ -49,6 +58,27 @@ define([
4958
return t[touchId].touchAction;
5059
},
5160

61+
updateScroll: function (touch) {
62+
if (t[touch.identifier].firstMove) {
63+
var touchInfo = t[touch.identifier];
64+
if (touchInfo.touchAction === utils.TouchAction.PAN_Y) {
65+
touchInfo.enforceTouchAction =
66+
canScroll(touchInfo.firstMove.startY, touchInfo.firstMove.startX, touch.pageY, touch.pageX);
67+
} else {
68+
if (touchInfo.touchAction === utils.TouchAction.PAN_X) {
69+
touchInfo.enforceTouchAction =
70+
canScroll(touchInfo.firstMove.startX, touchInfo.firstMove.startY, touch.pageX, touch.pageY);
71+
}
72+
}
73+
touchInfo.firstMove = false;
74+
}
75+
},
76+
77+
78+
isTouchActionEnforced: function (touchId) {
79+
return t[touchId].enforceTouchAction;
80+
},
81+
5282
getLastTouch: function (touchId) {
5383
return t[touchId].lastTouch;
5484
},

tests/touchActionPanXY.html

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<!DOCTYPE html>
2+
<!--
3+
-->
4+
<html>
5+
<head>
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<title>touch-action=PAN-X|Y</title>
9+
<script src="../../requirejs/require.js"></script>
10+
<script>
11+
require.config({
12+
baseUrl: "../.."
13+
});
14+
require([
15+
"dpointer/events",
16+
"requirejs-domready/domReady!"
17+
], function () {
18+
var msgLog = document.getElementById("msgLog");
19+
20+
function logMsg(msg, append) {
21+
msgLog.innerHTML = (append ? "<br>" : "") + msg +
22+
msgLog.innerHTML.substring(
23+
msgLog.innerHTML.indexOf("<br>"), msgLog.innerHTML.length
24+
);
25+
console.log(msg);
26+
}
27+
28+
function resetLog() {
29+
msgLog.innerHTML = "<br>";
30+
}
31+
32+
var VContainer = document.getElementById("VContainer");
33+
VContainer.addEventListener("click", function () {
34+
logMsg("--CLICK--", true);
35+
});
36+
37+
["pointerover", "pointerenter", "pointerdown", "pointermove",
38+
"pointerup", "pointerout", "pointerleave", "pointercancel"].forEach(function (name) {
39+
window.document.body.addEventListener(name, function (e) {
40+
if (e.type === "pointerover") {
41+
resetLog();
42+
}
43+
logMsg(e.type + " [" + (e.target.id || e.target.tagName) + "]", true);
44+
});
45+
});
46+
47+
logMsg(navigator.userAgent, true);
48+
logMsg("---", true);
49+
logMsg("CSS touch-action " + (("touchAction" in document.body.style) ? "is" : "NOT") +
50+
" supported by this user agent.", true);
51+
});
52+
</script>
53+
<style>
54+
#VContainer {
55+
position: relative;
56+
background-color: lightgreen;
57+
width: 50%;
58+
height: 300px;
59+
overflow: auto;
60+
-webkit-overflow-scrolling: touch;
61+
}
62+
63+
#VContent {
64+
position: relative;
65+
width: 100%;
66+
}
67+
68+
#HContainer {
69+
position: relative;
70+
background-color: lightgreen;
71+
width: 100%;
72+
height: 100px;
73+
overflow: auto;
74+
-webkit-overflow-scrolling: touch;
75+
}
76+
77+
#HContent {
78+
position: relative;
79+
width: 500%;
80+
height: auto;
81+
}
82+
83+
#msgLog {
84+
position: relative;
85+
text-align: right;
86+
float: right;
87+
width: 50%;
88+
background-color: lightblue;
89+
height: 300px;
90+
overflow: auto;
91+
}
92+
</style>
93+
</head>
94+
<body id="body">
95+
<h1>touch-action=PAN-X|Y</h1>
96+
<hr>
97+
<h4>PAN-Y: Scroll down/up: pointer must be cancelled. Scroll left/right: pointer events must be fired.</h4>
98+
<span id="msgLog"><br></span>
99+
100+
<div id="VContainer" touch-action="pan-y">
101+
<div id="VContent">
102+
<p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
103+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
104+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
105+
lobortis nisl ut aliquip ex ea commodo consequat.
106+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
107+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
108+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
109+
lobortis nisl ut aliquip ex ea commodo consequat.
110+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
111+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
112+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
113+
lobortis nisl ut aliquip ex ea commodo consequat.
114+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
115+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
116+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
117+
lobortis nisl ut aliquip ex ea commodo consequat.
118+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
119+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
120+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
121+
lobortis nisl ut aliquip ex ea commodo consequat.
122+
</p>
123+
</div>
124+
</div>
125+
<hr>
126+
<h4>PAN-X: Scroll down/up: pointer events must be fired. Scroll left/right: pointer must be cancelled.</h4>
127+
128+
<div id="HContainer" touch-action="pan-x">
129+
<div id="HContent">
130+
<p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
131+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
132+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
133+
lobortis nisl ut aliquip ex ea commodo consequat.
134+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
135+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
136+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
137+
lobortis nisl ut aliquip ex ea commodo consequat.
138+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
139+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
140+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
141+
lobortis nisl ut aliquip ex ea commodo consequat.
142+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
143+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
144+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
145+
lobortis nisl ut aliquip ex ea commodo consequat.
146+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
147+
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat.
148+
Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit
149+
lobortis nisl ut aliquip ex ea commodo consequat.
150+
</p>
151+
</div>
152+
</div>
153+
<hr>
154+
</body>
155+
</html>

0 commit comments

Comments
 (0)