Skip to content

Instantly share code, notes, and snippets.

@oranj
Created March 29, 2013 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oranj/5271621 to your computer and use it in GitHub Desktop.
Save oranj/5271621 to your computer and use it in GitHub Desktop.
Touch event pinch / zoom gesture library. jQuery based
(function($) {
var TOUCH_START = 'touchstart';
var TOUCH_MOVE = 'touchmove';
var TOUCH_END = 'touchend';
var num_touch_points = function(e) {
var o = e.originalEvent;
if (o.hasOwnProperty('touches')) {
return o.touches.length;
} else {
return 1;
}
};
var touch_points = function(e, multi_cancel) {
if (multi_cancel == undefined) { multi_cancel = true; }
var o = e.originalEvent;
var r = [];
if (o.hasOwnProperty('touches')) {
if (o.touches.length > 1 && multi_cancel) { return []; }
for (var i in o.touches) { if (o.touches.hasOwnProperty(i) && o.touches[i].hasOwnProperty('pageX')) {
r.push({'x':o.touches[i].pageX, 'y':o.touches[i].pageY});
}}
} else {
r.push({'x':o.pageX, 'y':o.pageY});
}
return r;
};
var point_distance = function(pointa, pointb) {
return Math.sqrt(Math.pow(pointa.x - pointb.x, 2) + Math.pow(pointa.y - pointb.y, 2));
};
var max_distance = function(pointa, points) {
var max = -1;
for (var i = 0; i < points.length; i++) {
var dist = point_distance(pointa, points[i]);
if (dist > max) { max = dist; }
}
return max;
};
var center_2d = function(points) {
var p = {'x':0, 'y':0}
for (var i = 0; i < points.length; i++) {
p.x += points[i].x;
p.y += points[i].y;
}
p.x /= points.length;
p.y /= points.length;
return p;
};
var center_and_radius = function(e) {
var touchPoints = touch_points(e, false);
var center = center_2d(touchPoints);
var radius = max_distance(center, touchPoints);
return { 'center': center, 'radius':radius };
};
$.fn.pinch = function(options) {
var settings = $.extend( {
'pinchstart' : function(e) { },
'pinchend' : function(e) { },
'pinchmove' : function(e) { }
}, options);
$(this)
.on('pinchmove', settings.pinchmove)
.on('pinchend', settings.pinchend)
.on('pinchstart', settings.pinchstart);
var __is_touch_down = true,
__original_center = null,
__original_radius = null,
__scale = 1,
__cd_data = {},
that = this;
$(this).bind(TOUCH_START, function(e) {
if (num_touch_points(e) == 2) {
var cd_data = center_and_radius(e);
__original_radius = cd_data.radius;
__original_center = cd_data.center;
__is_touch_down = true;
var _e = {
"centerX" : cd_data.center.x,
"centerY" : cd_data.center.y,
"radius" : cd_data.radius
};
$(this).trigger('pinchstart', _e);
e.preventDefault();
}
});
$(document)
.bind(TOUCH_MOVE, function(e) {
if (num_touch_points(e) == 2) {
var cd_data = center_and_radius(e);
if (! __is_touch_down) {
__original_center = cd_data.center;
__original_radius = cd_data.radius;
var _e = {
"centerX" : cd_data.center.x,
"centerY" : cd_data.center.y,
"radius" : cd_data.radius
};
$(that).trigger('pinchstart', _e);
__is_touch_down = true;
} else {
__scale = cd_data.radius / __original_radius;
__cd_data = cd_data;
var _e = {
"scale" : __scale,
"centerX" : __cd_data.center.x,
"centerY" : __cd_data.center.y,
"radius" : __cd_data.radius
};
$(that).trigger('pinchmove', _e);
}
e.preventDefault();
}
})
.bind(TOUCH_END, function(e) {
if (__is_touch_down) {
var _e = {
"scale" : __scale,
"centerX" : __cd_data.center.x,
"centerY" : __cd_data.center.y,
"radius" : __cd_data.radius
};
$(that).trigger('pinchend', _e);
__original_center = null;
__is_touch_down = false;
__oroginal_radius = null;
e.preventDefault();
}
});
};
})(jQuery);
$('#pincher').pinch({
'pinchstart':function(e, data) {
$('#console').text('start ' + print_r(data, true));
draw_circle(data);
},
'pinchend':function(e, data) {
$('#console').text('end ' + print_r(data, true));
draw_circle(data);
},
'pinchmove':function(e, data) {
$('#console').text('move ' + print_r(data, true));
draw_circle(data);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment