Enabling Touch Gestures in an HTML5 App in Intel AppUp®

We have flexibility when developing apps in HTML5 and publishing to Intel AppUp® using the HTML5 encapsulator. However, when we start developing apps for touch-enabled devices, we soon hit certain roadblocks. 

We googled the phrase “html5 touch events” anticipating some HTML5 touch examples and found Multi-touch web development as the first link from www.html5rocks.com website. We tried this example on the Chrome* browser, and everything worked fine. However, this won’t be the case when we encapsulate it with the Intel encapsulator. 

Intel uses the chromium embedded framework (CEF) behind the scenes. The Chrome browser supports HTML5. We develop our apps with HTML5 and test them without a hitch with Chrome. Everything, including touch gestures, works just great in Chrome. However, depending upon the version of CEF, we have seen instances where some of the HTML5 functionality does not work. One such example is touch gestures.

In this blog, I will show you the workaround I discovered for this problem. 

Intel has two versions of its encapsulator. Encapsulator 2.0 is the Alpha version and supports purchase APIs. Version 1.0 is the old version and is pretty stable. If you don’t have any in-app purchases in your application, then you can still use 1.0. We have different problems with 1.0 and 2.0 with respect to touch input. 

Encapsulator 1.0

With Encapsulator 1.0, you can still use touch events defined by HTML5. However, you cannot use them with addEventListner method. You need to define your events within the DOM element itself.

The following code will fail due to addEventListner. 

 
var divid = document.getElementById(' divid ');
var mydiv = document.getElementById(‘mydiv ');
mydiv.addEventListener('touchmove', function(e) {
  for(i =0;i < event.targetTouches.length;i++) {
    var touch = event.targetTouches[i];
   divid.innerHTML += “touch “ + i + “:<br>”;
    divid.innerHTML += “X:” +  touch.pageX + 'px';
   divid.innerHTML += “Y:” +  touch.pageY + 'px';
  }
}, false);
 

Instead of the above code, use inline DOM event attributes, and then this code will work fine.

<div id="gesture"></div>
<div id="directionx"></div>
<div id="directiony"></div>
<div id="mydiv" style="top:0px; left:0px; width: 800px; height: 600px;" ontouchmove="touchMove(event)" ontouchend="touchEnd(event)" ontouchstart="touchStart(event)"></div>

        
function touchMove(e) {
            endX = e.touches.item(0).pageX;
            endY = e.touches.item(0).pageY;
            e.preventDefault();
            return false;
        }

The above code makes the touch events work. Also, you can loop through the touch events from the event parameter to get the multiple touch points.To get gestures to work, we can use touchstart, touchmove, and touchend events. For example, start point, end point, and speed between the moves give the swipe gesture. The following code shows what type of gesture occurred.

         
var date1, date2;
        var startX, endX,startY,endY;
        function touchStart(e) {
//Register the start point
            startX = e.touches.item(0).pageX;
            startY = e.touches.item(0).pageY;
            date1 = new Date().getTime();
            e.preventDefault();
            return false;
        }
function touchMove(e) {
//Register the end point
            endX = e.touches.item(0).pageX;
            endY = e.touches.item(0).pageY;
            e.preventDefault();
            return false;
        }

        function touchEnd(e) {
            date2 = new Date().getTime();
            var datet = date2 - date1;
//If the time difference is more, then it would be a touch move otherwise, this would be a swipe gesture. 
            if (datet > 200)
                document.getElementById("gesture").innerHTML = "<b>Touchmove</b>";
            else {
                document.getElementById("gesture").innerHTML = "<b>Swipe</b>";
//If start X is greater than end X, then its left swipe gesture. Otherwise, it is right swipe.
                if (startX > endX) document.getElementById("directionx").innerHTML = "<b>Left Swipe</b>";
                else document.getElementById("directionx").innerHTML = "<b>Right Swipe</b>";

//If start Y is greater than end Y, top swipe gesture. Otherwise, it is swipe down.
                if (startY > endY) document.getElementById("directiony").innerHTML = "<b>Top Swipe</b>";
                else document.getElementById("directiony").innerHTML = "<b>Down Swipe</b>";
            }
            e.preventDefault();
            return false;
        }
 

Encapsulator 2.0

In encapsulator 2.0, touch events themselves won’t work. All the code defined above would remain the same except the event declarations. Instead of touch events, you will have to use the mouse.

<div id="ads" style="top:0px; left:0px; width: 800px; height: 600px;" onmousemove="touchMove(event)" onmouseup="touchEnd(event)" onmousedown="touchStart(event)"></div>

If you wish to use open source framework instead of the custom development defined here, you can use http://eightmedia.github.com/hammer.js/. This framework works pretty well with encapsulator 2.0.

Tips:

If you want to find out if the device supports touch events or not, you can use following piece of code.

 if("ontouchmove" in window)return true;

2. When you touch and move, your selected control may get selected. For example, if you are scrolling (touchscroll) on an image, instead of scrolling, the image may get selected (like CTRL + A). For this problem, you can use following CSS styles for that tag.

-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;

Hope this helps!!

*Other names and brands may be claimed as the property of others.

Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.