Skip to content

Conversation

@codecurve
Copy link

I've only tested touch interaction on Firefox and Google Chrome, both on Android on a Samsung Galaxy S3.
Testing of mouse interaction done on MacOS: Safari, Chrome, Firefox, and seems to work as before.

The tutorial text would need to be updated, here is a suggestion:
Title: WebGL Lesson 11 – spheres, rotation matrices, and mouse and touch events.

First paragraph:
... which the viewer can spin around using the mouse or touch screen.

First code snippet:
Remove:

        document.onmouseup = handleMouseUp;

Replace with:

        document.onmouseup = handleMouseUpOrTouchEnd;

Then, after:

        document.onmousemove = handleMouseMove;

Insert, also in red:

        canvas.addEventListener("touchstart", handleTouchStart, false);
        canvas.addEventListener("touchend", handleMouseUpOrTouchEnd, false);
        canvas.addEventListener("touchcancel", handleMouseUpOrTouchEnd, false);
        canvas.addEventListener("touchleave", handleMouseUpOrTouchEnd, false);
        canvas.addEventListener("touchmove", handleTouchMove, false);

In the paragraph just after the code snippet:
Change "These three new lines allow us to ..." to "The first three lines of these new lines allow us to ..."

After that paragraph, insert:
__The next 6 lines of the new lines set-up the handling of touch screen events, which are similar in many ways to mouse events. For more information on handling touch events in conjunction with mouse events, see
https://developer.mozilla.org/en-US/docs/Web/Guide/DOM/Events/Touch_events. In a nutshell, we only want to process touch events for touches that originated on the canvas, and for touches this means attaching all callbacks to the canvas. Note that there are 3 ways the touch can end.

Paragraph starting "Immediately above the initBuffers ...":
Change first line: Immediately above the initBuffers function are the six functions that deal with the mouse and touches.

Next paragraph:
Change " When the user drags the mouse around, we get a sequence of mouse-move events"
to
" When the user drags the mouse (or touch location) around, we get a sequence of mouse-move (or touch-move) events"

Insert the following paragraph just before "So, with all that explained, the code below should be pretty clear:":
"Handling touch events are similar to handling mouse events. The touch event handlers for touch-start and touch-move call evt.preventDefault() since otherwise a mouse event is also processed. Touch-end and mouse-up use the same callback. Too keep things simple, this example also tries to avoid having to handle multi-touch gestures on the canvas, although some cool multi-touch interactions are easy to imagine. It does this by checking that the number of touches is 1, and that the touch id matches the one that has been used since the touch started."

Change the code snippet that follows to the new (almost identical) code:

    var mouseDownOrTouchActive = false;
    var lastMouseX = null;
    var lastMouseY = null;
    var touchId = null;

    var moonRotationMatrix = mat4.create();
    mat4.identity(moonRotationMatrix);

    function handleMouseDown(event) {
        mouseDownOrTouchActive = true;
        lastMouseX = event.clientX;
        lastMouseY = event.clientY;
    }

    function handleTouchStart(evt) {
      evt.preventDefault();
      var touches = evt.targetTouches;

      if (touches.length == 1 && !mouseDownOrTouchActive ) {
        touchId = touches[0].identifier; 
        lastMouseX = touches[0].pageX, 
        lastMouseY = touches[0].pageY;
      }
    }

    function handleMouseUpOrTouchEnd(event) {
        mouseDownOrTouchActive = false;
    }

    function handleMouseMove(event) {
        if (!mouseDownOrTouchActive) {
            return;
        }
        var newX = event.clientX;
        var newY = event.clientY;

        processDrag(newX, newY);
    }

    function handleTouchMove(evt) {
      evt.preventDefault();
      var touches = evt.targetTouches;

      if (touches.length == 1 && touchId == touches[0].identifier) {
        var newX = touches[0].pageX;
        var newY = touches[0].pageY;
        processDrag(newX, newY);
      }
    }

    function processDrag(newX, newY) {
        var deltaX = newX - lastMouseX
        var newRotationMatrix = mat4.create();
        mat4.identity(newRotationMatrix);
        mat4.rotate(newRotationMatrix, degToRad(deltaX / 10), [0, 1, 0]);

        var deltaY = newY - lastMouseY;
        mat4.rotate(newRotationMatrix, degToRad(deltaY / 10), [1, 0, 0]);

        mat4.multiply(newRotationMatrix, moonRotationMatrix, moonRotationMatrix);

        lastMouseX = newX
        lastMouseY = newY;
    }

Randall Britten added 4 commits July 18, 2013 10:47
… single touch dragging is processed.

Also, removed div, since touch callbacks from canvas directly were sufficient.
…g functions for neater flow.

Also, some minor whitespace tidy-ups.
…ulti-touch" misinterpretations, based on playing around.
brianfoshee pushed a commit to brianfoshee/webgl-lessons that referenced this pull request Feb 27, 2014
Remove gl.viewportWidth and gl.viewportHeight
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant