Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make example work on touch screen as well. #1

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

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