Search code examples
javascriptthree.jstouchaugmented-realityaframe

Three.js OnDocumentMouseDown does not work with touch screen?


Full code in this Glitch project. https://glitch.com/~quickest-catshark

I have declared a custom AFRAME component in public/components.js that rotates the item when dragging with mouse.

AFRAME.registerComponent('drag-rotate-component', {
    schema: { speed: { default: 10 } },
    init: function () {
        this.ifMouseDown = false;
        this.x_cord = 0;
        this.y_cord = 0;
        document.addEventListener('mousedown', this.OnDocumentMouseDown.bind(this));
        document.addEventListener('mouseup', this.OnDocumentMouseUp.bind(this));
        document.addEventListener('mousemove', this.OnDocumentMouseMove.bind(this));
    },
    // When mouse down, save x and y coordinates of mouse position
    OnDocumentMouseDown: function (event) {
        this.ifMouseDown = true;
        this.x_cord = event.clientX;
        this.y_cord = event.clientY;
    },
    OnDocumentMouseUp: function () {
        this.ifMouseDown = false;

        // Save rotation to localstorage
        let rotation = this.el.object3D.rotation.z;
        localStorage.setItem('angle', rotation);
    },
    OnDocumentMouseMove: function (event) {
        if (this.ifMouseDown) {
            // Get difference between current mouse position and previous mouse position
            var temp_x = event.clientX - this.x_cord;
            var temp_y = event.clientY - this.y_cord;

            this.el.object3D.rotation.z = temp_x * this.data.speed / 1000;
        }
    }
});

The code works as intended in the browser.

But when I access it from Chrome in my mobile phone, nothing happens when I drag my finger in the area. Doesn't work in my Surface Pro touch tablet either.

How do I get it to work in touch devices?

I tried the answe given in this question Mouse events not working in mobile

Use event.touches[0].clientX and event.touches[0].clientY. But these return undefined.


Solution

  • You need to use touchstart, touchmove, touchend for touch and in those events you'd use event.touches[0].clientX and clientY

    Further, you want probably want your event handlers to not be passive so that in touchstart you can tell the browser to ignore the touch otherwise the page will scroll/zoom/etc...

    You can find an example here

    Supporting Touch Interface in a canvas