mirror of https://github.com/luileito/jsketch.git
Added multitouch support
This commit is contained in:
parent
570c68485e
commit
3efb83c9c5
|
|
@ -54,14 +54,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var sketch = new jSketch(this, options.graphics);
|
var sketch = new jSketch(this, options.graphics);
|
||||||
|
// sketch.beginPath();
|
||||||
// Flag drawing state on a per-canvas basis.
|
// Flag drawing state on a per-canvas basis.
|
||||||
sketch.isDrawing = false;
|
sketch.isDrawing = false;
|
||||||
// Reconfigure element data.
|
// Reconfigure element data.
|
||||||
elem.data(_ns, {
|
elem.data(_ns, {
|
||||||
// All strokes will be stored here.
|
// All strokes will be stored here.
|
||||||
strokes: [],
|
strokes: [],
|
||||||
// This array represents a single stroke.
|
// This will store one stroke per touching finger.
|
||||||
coords: [],
|
coords: {},
|
||||||
// Date of first coord, used as time origin.
|
// Date of first coord, used as time origin.
|
||||||
timestamp: new Date().getTime(),
|
timestamp: new Date().getTime(),
|
||||||
// Save a pointer to the drawing canvas (jSketch instance).
|
// Save a pointer to the drawing canvas (jSketch instance).
|
||||||
|
|
@ -127,8 +128,7 @@
|
||||||
var elem = $(this), data = elem.data(_ns), options = data.options;
|
var elem = $(this), data = elem.data(_ns), options = data.options;
|
||||||
data.sketch.clear();
|
data.sketch.clear();
|
||||||
data.strokes = [];
|
data.strokes = [];
|
||||||
data.coords = [];
|
data.coords = {};
|
||||||
// Trigger clear event, if need be.
|
|
||||||
if (typeof options.events.clear === 'function') {
|
if (typeof options.events.clear === 'function') {
|
||||||
options.events.clear(elem, data);
|
options.events.clear(elem, data);
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +148,6 @@
|
||||||
return this.each(function(){
|
return this.each(function(){
|
||||||
var elem = $(this), data = elem.data(_ns), options = data.options;
|
var elem = $(this), data = elem.data(_ns), options = data.options;
|
||||||
elem.sketchable('destroy').sketchable(opts);
|
elem.sketchable('destroy').sketchable(opts);
|
||||||
// Trigger reset event, if need be.
|
|
||||||
if (typeof options.events.reset === 'function') {
|
if (typeof options.events.reset === 'function') {
|
||||||
options.events.reset(elem, data);
|
options.events.reset(elem, data);
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +172,6 @@
|
||||||
elem.unbind("touchmove", touchHandler);
|
elem.unbind("touchmove", touchHandler);
|
||||||
}
|
}
|
||||||
elem.removeData(_ns);
|
elem.removeData(_ns);
|
||||||
// Trigger destroy event, if need be.
|
|
||||||
if (typeof options.events.destroy === 'function') {
|
if (typeof options.events.destroy === 'function') {
|
||||||
options.events.destroy(elem, data);
|
options.events.destroy(elem, data);
|
||||||
}
|
}
|
||||||
|
|
@ -266,6 +264,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function getMousePos(e) {
|
function getMousePos(e) {
|
||||||
var elem = $(e.target), pos = elem.offset();
|
var elem = $(e.target), pos = elem.offset();
|
||||||
return {
|
return {
|
||||||
|
|
@ -274,65 +273,69 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function saveMousePos(data, pt) {
|
function saveMousePos(idx, data, pt) {
|
||||||
var time = (new Date).getTime();
|
var time = (new Date).getTime();
|
||||||
if (data.options.relTimestamps) {
|
if (data.options.relTimestamps) {
|
||||||
// The first timestamp is relative to initialization time;
|
// The first timestamp is relative to initialization time;
|
||||||
// thus fix it so that it is relative to the timestamp of the first stroke.
|
// thus fix it so that it is relative to the timestamp of the first stroke.
|
||||||
if (data.strokes.length === 0 && data.coords.length === 0) data.timestamp = time;
|
if (data.strokes.length === 0 && data.coords[idx].length === 0) data.timestamp = time;
|
||||||
time -= data.timestamp;
|
time -= data.timestamp;
|
||||||
}
|
}
|
||||||
data.coords.push([ pt.x, pt.y, time, +data.sketch.isDrawing ]);
|
data.coords[idx].push([ pt.x, pt.y, time, +data.sketch.isDrawing ]);
|
||||||
};
|
};
|
||||||
|
|
||||||
function mousemoveHandler(e) {
|
function mousemoveHandler(e, idx) {
|
||||||
|
if (typeof idx === 'undefined') idx = 0;
|
||||||
|
|
||||||
var elem = $(e.target), data = elem.data(_ns), options = data.options;
|
var elem = $(e.target), data = elem.data(_ns), options = data.options;
|
||||||
//if (!options.mouseupMovements && !data.sketch.isDrawing) return;
|
//if (!options.mouseupMovements && !data.sketch.isDrawing) return;
|
||||||
// This would grab all penup strokes AFTER drawing something on the canvas for the first time.
|
// This would grab all penup strokes AFTER drawing something on the canvas for the first time.
|
||||||
if ( (!options.mouseupMovements || data.strokes.length === 0) && !data.sketch.isDrawing ) return;
|
if ( (!options.mouseupMovements || data.strokes.length === 0) && !data.sketch.isDrawing ) return;
|
||||||
|
|
||||||
var p = getMousePos(e);
|
var p = getMousePos(e);
|
||||||
// Save mouse coords as soon as possible.
|
|
||||||
saveMousePos(data, p);
|
|
||||||
if (data.sketch.isDrawing) {
|
if (data.sketch.isDrawing) {
|
||||||
data.sketch.lineTo(p.x, p.y).stroke();
|
var last = data.coords[idx][ data.coords[idx].length - 1 ];
|
||||||
|
data.sketch.beginPath().line(last[0], last[1], p.x, p.y).closePath();
|
||||||
}
|
}
|
||||||
// Trigger mousemove event, if need be.
|
saveMousePos(idx, data, p);
|
||||||
if (typeof options.events.mousemove === 'function') {
|
if (typeof options.events.mousemove === 'function') {
|
||||||
options.events.mousemove(elem, data, e);
|
options.events.mousemove(elem, data, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function mousedownHandler(e) {
|
function mousedownHandler(e, idx) {
|
||||||
|
if (typeof idx === 'undefined') idx = 0;
|
||||||
|
|
||||||
var elem = $(e.target), data = elem.data(_ns), options = data.options;
|
var elem = $(e.target), data = elem.data(_ns), options = data.options;
|
||||||
var p = getMousePos(e);
|
|
||||||
// Save mouse coords as soon as possible, but don't mix mouseup and mousedown points in the same stroke.
|
|
||||||
if (data.coords.length > 0) {
|
|
||||||
data.strokes.push(data.coords);
|
|
||||||
data.coords = [];
|
|
||||||
}
|
|
||||||
saveMousePos(data, p);
|
|
||||||
// Flag drawing state.
|
|
||||||
data.sketch.isDrawing = true;
|
data.sketch.isDrawing = true;
|
||||||
data.sketch.beginPath();
|
var p = getMousePos(e);
|
||||||
|
|
||||||
// Mark visually 1st point of stroke.
|
// Mark visually 1st point of stroke.
|
||||||
if (options.graphics.firstPointSize > 0) {
|
if (options.graphics.firstPointSize > 0) {
|
||||||
data.sketch.fillCircle(p.x, p.y, options.graphics.firstPointSize);
|
data.sketch.fillCircle(p.x, p.y, options.graphics.firstPointSize);
|
||||||
}
|
}
|
||||||
// Trigger mousedown event, if need be.
|
// Ensure that coords is properly initialized.
|
||||||
|
if (!data.coords[idx]) {
|
||||||
|
data.coords[idx] = [];
|
||||||
|
}
|
||||||
|
// Don't mix mouseup and mousedown in the same stroke.
|
||||||
|
if (data.coords[idx].length > 0) {
|
||||||
|
data.strokes.push(data.coords[idx]);
|
||||||
|
data.coords[idx] = [];
|
||||||
|
}
|
||||||
|
saveMousePos(idx, data, p);
|
||||||
if (typeof options.events.mousedown === 'function') {
|
if (typeof options.events.mousedown === 'function') {
|
||||||
options.events.mousedown(elem, data, e);
|
options.events.mousedown(elem, data, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function mouseupHandler(e) {
|
function mouseupHandler(e, idx) {
|
||||||
|
if (typeof idx === 'undefined') idx = 0;
|
||||||
|
|
||||||
var elem = $(e.target), data = elem.data(_ns), options = data.options;
|
var elem = $(e.target), data = elem.data(_ns), options = data.options;
|
||||||
// Reset state.
|
|
||||||
data.sketch.isDrawing = false;
|
data.sketch.isDrawing = false;
|
||||||
data.sketch.closePath();
|
data.strokes.push(data.coords[idx]);
|
||||||
data.strokes.push(data.coords);
|
data.coords[idx] = [];
|
||||||
data.coords = [];
|
|
||||||
// Trigger mouseup event, if need be.
|
|
||||||
if (typeof options.events.mouseup === 'function') {
|
if (typeof options.events.mouseup === 'function') {
|
||||||
options.events.mouseup(elem, data, e);
|
options.events.mouseup(elem, data, e);
|
||||||
}
|
}
|
||||||
|
|
@ -341,28 +344,34 @@
|
||||||
function touchHandler(e) {
|
function touchHandler(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var elem = $(e.target);
|
var elem = $(e.target);
|
||||||
var touch = e.originalEvent.changedTouches[0];
|
var touch = e.originalEvent.changedTouches;
|
||||||
// Copy original event properties to touch event.
|
|
||||||
for (var o in e) {
|
|
||||||
touch[o] = e[o];
|
|
||||||
}
|
|
||||||
// Remove (emulated) mouse events on mobile devices.
|
// Remove (emulated) mouse events on mobile devices.
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case "touchstart":
|
case "touchstart":
|
||||||
elem.unbind(e.type, mousedownHandler);
|
elem.unbind(e.type, mousedownHandler);
|
||||||
mousedownHandler(touch);
|
for (var i = 1, t = touch[i-1]; i <= touch.length; i++) {
|
||||||
|
for (var o in e) t[o] = e[o];
|
||||||
|
mousedownHandler(t, t.identifier);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "touchmove":
|
case "touchmove":
|
||||||
elem.unbind(e.type, mousemoveHandler);
|
elem.unbind(e.type, mousemoveHandler);
|
||||||
mousemoveHandler(touch);
|
for (var i = 1, t = touch[i-1]; i <= touch.length; i++) {
|
||||||
|
for (var o in e) t[o] = e[o];
|
||||||
|
mousemoveHandler(t, t.identifier);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "touchend":
|
case "touchend":
|
||||||
elem.unbind(e.type, mouseupHandler);
|
elem.unbind(e.type, mouseupHandler);
|
||||||
mouseupHandler(touch);
|
for (var i = 1, t = touch[i-1]; i <= touch.length; i++) {
|
||||||
|
for (var o in e) t[o] = e[o];
|
||||||
|
mouseupHandler(t, t.identifier);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
* jQuery sketchable | v1.7 | Luis A. Leiva | MIT license
|
* jQuery sketchable | v1.7 | Luis A. Leiva | MIT license
|
||||||
* This is a jQuery plugin for the jSketch drawing class.
|
* This is a jQuery plugin for the jSketch drawing class.
|
||||||
*/
|
*/
|
||||||
(function(g){var e="sketchable";var b={init:function(k){var j=g.extend(true,{},g.fn.sketchable.defaults,k||{});return this.each(function(){var l=g(this),m=l.data(e);if(!m){if(j.interactive){l.bind("mousedown",h);l.bind("mouseup",i);l.bind("mousemove",f);l.bind("touchstart",d);l.bind("touchend",d);l.bind("touchmove",d);this.onselectstart=function(){return false}}}var n=new jSketch(this,j.graphics);n.isDrawing=false;l.data(e,{strokes:[],coords:[],timestamp:new Date().getTime(),sketch:n,options:j});if(typeof j.events.init==="function"){j.events.init(l,l.data(e))}})},strokes:function(j){if(j){return this.each(function(){var l=g(this),m=l.data(e);m.strokes=j})}else{var k=g(this).data(e);return k.strokes}},handler:function(j){return this.each(function(){var k=g(this),l=k.data(e);j(k,l)})},clear:function(){return this.each(function(){var k=g(this),l=k.data(e),j=l.options;l.sketch.clear();l.strokes=[];l.coords=[];if(typeof j.events.clear==="function"){j.events.clear(k,l)}})},reset:function(j){return this.each(function(){var l=g(this),m=l.data(e),k=m.options;l.sketchable("destroy").sketchable(j);if(typeof k.events.reset==="function"){k.events.reset(l,m)}})},destroy:function(){return this.each(function(){var k=g(this),l=k.data(e),j=l.options;if(j.interactive){k.unbind("mousedown",h);k.unbind("mouseup",i);k.unbind("mousemove",f);k.unbind("touchstart",d);k.unbind("touchend",d);k.unbind("touchmove",d)}k.removeData(e);if(typeof j.events.destroy==="function"){j.events.destroy(k,l)}})}};g.fn.sketchable=function(j){if("methods functions hooks".split(" ").indexOf(j)>-1){return b}else{if(b[j]){return b[j].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof j==="object"||!j){return b.init.apply(this,arguments)}else{g.error("Method "+j+' does not exist. See jQuery.sketchable("methods").')}}}return this};g.fn.sketchable.defaults={interactive:true,mouseupMovements:false,relTimestamps:false,events:{},graphics:{firstPointSize:3,lineWidth:3,strokeStyle:"#F0F",fillStyle:"#F0F",lineCap:"round",lineJoin:"round",miterLimit:10}};function c(k){var j=g(k.target),l=j.offset();return{x:Math.round(k.pageX-l.left),y:Math.round(k.pageY-l.top)}}function a(j,l){var k=(new Date).getTime();if(j.options.relTimestamps){if(j.strokes.length===0&&j.coords.length===0){j.timestamp=k}k-=j.timestamp}j.coords.push([l.x,l.y,k,+j.sketch.isDrawing])}function f(n){var k=g(n.target),l=k.data(e),j=l.options;if((!j.mouseupMovements||l.strokes.length===0)&&!l.sketch.isDrawing){return}var m=c(n);a(l,m);if(l.sketch.isDrawing){l.sketch.lineTo(m.x,m.y).stroke()}if(typeof j.events.mousemove==="function"){j.events.mousemove(k,l,n)}}function h(n){var k=g(n.target),l=k.data(e),j=l.options;var m=c(n);if(l.coords.length>0){l.strokes.push(l.coords);l.coords=[]}a(l,m);l.sketch.isDrawing=true;l.sketch.beginPath();if(j.graphics.firstPointSize>0){l.sketch.fillCircle(m.x,m.y,j.graphics.firstPointSize)}if(typeof j.events.mousedown==="function"){j.events.mousedown(k,l,n)}}function i(m){var k=g(m.target),l=k.data(e),j=l.options;l.sketch.isDrawing=false;l.sketch.closePath();l.strokes.push(l.coords);l.coords=[];if(typeof j.events.mouseup==="function"){j.events.mouseup(k,l,m)}}function d(k){k.preventDefault();var j=g(k.target);var m=k.originalEvent.changedTouches[0];for(var l in k){m[l]=k[l]}switch(k.type){case"touchstart":j.unbind(k.type,h);h(m);break;case"touchmove":j.unbind(k.type,f);f(m);break;case"touchend":j.unbind(k.type,i);i(m);break;default:return}}})(jQuery);
|
(function(g){var e="sketchable";var b={init:function(k){var j=g.extend(true,{},g.fn.sketchable.defaults,k||{});return this.each(function(){var l=g(this),m=l.data(e);if(!m){if(j.interactive){l.bind("mousedown",h);l.bind("mouseup",i);l.bind("mousemove",f);l.bind("touchstart",d);l.bind("touchend",d);l.bind("touchmove",d);this.onselectstart=function(){return false}}}var n=new jSketch(this,j.graphics);n.isDrawing=false;l.data(e,{strokes:[],coords:{},timestamp:new Date().getTime(),sketch:n,options:j});if(typeof j.events.init==="function"){j.events.init(l,l.data(e))}})},strokes:function(j){if(j){return this.each(function(){var l=g(this),m=l.data(e);m.strokes=j})}else{var k=g(this).data(e);return k.strokes}},handler:function(j){return this.each(function(){var k=g(this),l=k.data(e);j(k,l)})},clear:function(){return this.each(function(){var k=g(this),l=k.data(e),j=l.options;l.sketch.clear();l.strokes=[];l.coords={};if(typeof j.events.clear==="function"){j.events.clear(k,l)}})},reset:function(j){return this.each(function(){var l=g(this),m=l.data(e),k=m.options;l.sketchable("destroy").sketchable(j);if(typeof k.events.reset==="function"){k.events.reset(l,m)}})},destroy:function(){return this.each(function(){var k=g(this),l=k.data(e),j=l.options;if(j.interactive){k.unbind("mousedown",h);k.unbind("mouseup",i);k.unbind("mousemove",f);k.unbind("touchstart",d);k.unbind("touchend",d);k.unbind("touchmove",d)}k.removeData(e);if(typeof j.events.destroy==="function"){j.events.destroy(k,l)}})}};g.fn.sketchable=function(j){if("methods functions hooks".split(" ").indexOf(j)>-1){return b}else{if(b[j]){return b[j].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof j==="object"||!j){return b.init.apply(this,arguments)}else{g.error("Method "+j+' does not exist. See jQuery.sketchable("methods").')}}}return this};g.fn.sketchable.defaults={interactive:true,mouseupMovements:false,relTimestamps:false,events:{},graphics:{firstPointSize:3,lineWidth:3,strokeStyle:"#F0F",fillStyle:"#F0F",lineCap:"round",lineJoin:"round",miterLimit:10}};function c(k){var j=g(k.target),l=j.offset();return{x:Math.round(k.pageX-l.left),y:Math.round(k.pageY-l.top)}}function a(j,k,m){var l=(new Date).getTime();if(k.options.relTimestamps){if(k.strokes.length===0&&k.coords[j].length===0){k.timestamp=l}l-=k.timestamp}k.coords[j].push([m.x,m.y,l,+k.sketch.isDrawing])}function f(q,j){if(typeof j==="undefined"){j=0}var m=g(q.target),n=m.data(e),k=n.options;if((!k.mouseupMovements||n.strokes.length===0)&&!n.sketch.isDrawing){return}var o=c(q);if(n.sketch.isDrawing){var l=n.coords[j][n.coords[j].length-1];n.sketch.beginPath().line(l[0],l[1],o.x,o.y).closePath()}a(j,n,o);if(typeof k.events.mousemove==="function"){k.events.mousemove(m,n,q)}}function h(o,j){if(typeof j==="undefined"){j=0}var l=g(o.target),m=l.data(e),k=m.options;m.sketch.isDrawing=true;var n=c(o);if(k.graphics.firstPointSize>0){m.sketch.fillCircle(n.x,n.y,k.graphics.firstPointSize)}if(!m.coords[j]){m.coords[j]=[]}if(m.coords[j].length>0){m.strokes.push(m.coords[j]);m.coords[j]=[]}a(j,m,n);if(typeof k.events.mousedown==="function"){k.events.mousedown(l,m,o)}}function i(n,j){if(typeof j==="undefined"){j=0}var l=g(n.target),m=l.data(e),k=m.options;m.sketch.isDrawing=false;m.strokes.push(m.coords[j]);m.coords[j]=[];if(typeof k.events.mouseup==="function"){k.events.mouseup(l,m,n)}}function d(m){m.preventDefault();var l=g(m.target);var p=m.originalEvent.changedTouches;switch(m.type){case"touchstart":l.unbind(m.type,h);for(var k=1,j=p[k-1];k<=p.length;k++){for(var n in m){j[n]=m[n]}h(j,j.identifier)}break;case"touchmove":l.unbind(m.type,f);for(var k=1,j=p[k-1];k<=p.length;k++){for(var n in m){j[n]=m[n]}f(j,j.identifier)}break;case"touchend":l.unbind(m.type,i);for(var k=1,j=p[k-1];k<=p.length;k++){for(var n in m){j[n]=m[n]}i(j,j.identifier)}break;default:return}return false}})(jQuery);
|
||||||
Loading…
Reference in New Issue