Search code examples
javascriptiosiphonesafari3dtouch

How can I access iPhone's new 3D touch in Safari with Javascript?


Apple has announced that with its new iPhone 6S and 6S+, users can now use pressure to interact with their apps. Is there a JavaScript API for web developers to take advantage of this new functionality on standard websites as well? If so, how can it be implemented?


Solution

  • Yes, according to the W3C, a new force property has been recently added to the spec of the Touch interface, which ranges from 0 (min force) to 1 (max force). This is already available for Safari on iOS9 (not sure if Chrome, or other browsers have implemented it yet).

    Quick answer:

    To access this property, simply invoke

    touchForce = evt.originalEvent.touches[0].force;
    

    within a touchstart or touchmove event listener.

    There are a few problems with this implementation:

    • On touchstart, the force will be very close to 0, as it's called as soon as the first sign of pressure is detected.
    • The touchstart event won't fire again if pressure is increased or decreased.
    • touchmove isn't reliable because you have to wait for position to change before the new force is read, which won't always be the case.

    Solution:

    To remedy this, you can set a timeout that evaluates this force every few milliseconds after touchstart and then clear the timeout on touchend.

    var tO = 0;
    $("#div1").on("touchstart", startTouch);
    $("#div1").on("touchend", endTouch);
    
    function startTouch(evt){
        evt.preventDefault();
        touchForce = evt.originalEvent.touches[0].force;
        tO = window.setTimeout(function(){startTouch(evt)}, 100);
        // Do something with touchForce
    }
    
    function endTouch(){
        touchForce = 0;
        window.clearTimeout(tO);
        // Do something else
    }
    

    Try it out in this CodePen I created

    It's a bit hacky, but it works. Maybe in the future they'll create a new forcechange event, but this is all we have for now.

    Excuse the JQuery, I used it to illustrate the point more quickly.