Javascript zoom and rotate using gesturechange and gestureend
Asked Answered
C

2

19

I am working on some touch events and gestures, I want to be able to zoom and rotate the object, I have successfully made it draggable but the gestures are giving me trouble. The gestures are working but they are choppy, whenever you pinch it to zoom in or zoom out or try to rotate it, it jumps from finger to finger.

Here is my code for reference.

var width = 300; var height = 300; var rotation = 0;
$('.dynamic').live("gesturechange gestureend", function(e){
var orig = e.originalEvent;

if(e.type == 'gesturechange'){
    e.preventDefault();
    $(this).css("width", parseFloat(width) * orig.scale);
    $(this).css("height", parseFloat(height) * orig.scale);
    $(this).css("-webkit-transform","rotate(" + ((parseFloat(rotation) + orig.rotation) % 360) + "deg)");
}else if(e.type == 'gestureend'){
    a.w[ids] = parseFloat(width) * orig.scale;
    a.h[ids] = parseFloat(height) * orig.scale;
    a.rotation[ids] = (parseFloat(rotation) + orig.rotation) % 360;
}
});

Are there anyways to make this smooth, and prevent it from jumping from fingers, or is the approach I took wrong. In need of some tips and tricks and help

found a solution

Seems like the my touch event for drag interfered with the gestures thats why it kept jumping from finger to finger, the way around this was to not use gestures instead count the touches on the object and use touch start,end and change instead.

Here is the code

var touches = 0; var width = 300; var height = 300; var rotation = 0;
$('.dynamic').live("touchstart touchmove touchend", function(e){
var orig = e.originalEvent;   

if(e.type == 'touchstart'){
 if(orig.touches.length == 1){
    touches = 1; 
 }else if(orig.touches.length == 2){
    touches = 2;
 }
}else if(e.type == 'touchmove'){
 e.preventDefault();
 if(touches == 2){
        $(this).css("width", parseFloat(width) * orig.scale);
        $(this).css("height", parseFloat(height) * orig.scale);
        $(this).css("-webkit-transform","rotate(" + ((parseFloat(rotation) + orig.rotation) % 360) + "deg)");
 }
}else if(e.type == 'touchend'){
    if(touches == 2){
        a.w[ids] = parseFloat(width) * orig.scale;
        a.h[ids] = parseFloat(height) * orig.scale;
        a.rotation[ids] = (parseFloat(rotation) + orig.rotation) % 360;
    }
}
});
Coupe answered 23/6, 2011 at 18:1 Comment(5)
Many thanks for posting your answer! The usual thing to do would be to post it as an answer, rather than editing it into the question. (There's nothing wrong with answering your own question.)Cryptozoic
it does not let me answer it just yet since I am new on hereCoupe
Did your first approach work on Android 2.x? I want to support pinch gesture but the second approach (fine-grained touch support) only works on iOS (and Android 3.0/tablets, and WebOS?). Thanks for posting your solution!Stertor
Changing height and width to a scale transform could also make the result smootherStertor
AFAIK touch event objects do not have a scale property (unlike gesture event objects). By which conditions do you get it?Johannisberger
C
10

Your solution works, but it's not the most elegant: you can still use your first piece of code and rely on the gesture events.
All you have to do is make sure that the touch event handlers do not interfere with your gesture ones.
Just add this into the touch event handlers:

$('.dynamic').live("touchstart touchmove touchend", function(e){
    if(e.originalEvent.touches.length > 1)
        return;
    /* your touch code here */
});

and then use your existing gesture code :

$('.dynamic').live("gesturechange gestureend", function(e){
     /* your gesture code here */
});

This should work because the gesture events are triggered only there are two or more fingers touching the screen, and no other code executes when this happens, because the touch event handlers respond only to a single touch.

Chronology answered 17/9, 2011 at 18:16 Comment(0)
L
0

Maybe jquery is not the best for this task. You might think about using sencha touch. It already does what you wanted very nicely. Have a look at the demos. Depending on what you want to do jQuery Mobile would also be a good choice.

Lockup answered 22/9, 2011 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.