diff --git a/jquery.sketchable.js b/jquery.sketchable.js index 3446ad4..54c33c2 100644 --- a/jquery.sketchable.js +++ b/jquery.sketchable.js @@ -118,12 +118,13 @@ */ clear: function() { return this.each(function() { - var elem = $(this), data = elem.data(_ns), options = data.options; - data.sketch.clear(); - data.strokes = []; - data.coords = {}; - - if (typeof options.events.clear === 'function') { + var elem = $(this), data = elem.data(_ns) || {}, options = data.options; + if (data.sketch) { + data.sketch.clear(); + data.strokes = []; + data.coords = {}; + } + if (options && typeof options.events.clear === 'function') { options.events.clear(elem, data); } }); @@ -139,10 +140,10 @@ */ reset: function(opts) { 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); - if (typeof options.events.reset === 'function') { + if (options && typeof options.events.reset === 'function') { options.events.reset(elem, data); } }); @@ -155,7 +156,7 @@ */ destroy: 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; if (options.interactive) { elem.unbind("mouseup", mouseupHandler); elem.unbind("mousemove", mousemoveHandler); @@ -166,7 +167,7 @@ } elem.removeData(_ns); - if (typeof options.events.destroy === 'function') { + if (options && typeof options.events.destroy === 'function') { options.events.destroy(elem, data); } }); @@ -240,8 +241,10 @@ // Indicate whether non-drawing strokes should be registered as well. // Notice that the last mouseUp stroke is never recorded, as the user has already finished drawing. mouseupMovements: false, - // Inidicate whether timestamps should be relative (start at time 0) or absolute (start at Unix epoch). + // Indicate whether timestamps should be relative (start at time 0) or absolute (start at Unix epoch). relTimestamps: false, + // Enable multitouch drawing. + multitouch: true, // Event callbacks. events: { // init: function(elem, data){ }, @@ -322,10 +325,15 @@ * @private */ function touchdownHandler(e) { + var elem = $(e.target), data = elem.data(_ns), options = data.options; var touches = e.originalEvent.changedTouches; - for (var i = 0; i < touches.length; i++) { - var touch = touches[i]; - downHandler(touch); + if (options.multitouch) { + for (var i = 0; i < touches.length; i++) { + var touch = touches[i]; + downHandler(touch); + } + } else { + downHandler(touches[0]); } e.preventDefault(); }; @@ -334,10 +342,15 @@ * @private */ function touchmoveHandler(e) { + var elem = $(e.target), data = elem.data(_ns), options = data.options; var touches = e.originalEvent.changedTouches; - for (var i = 0; i < touches.length; i++) { - var touch = touches[i]; - moveHandler(touch); + if (options.multitouch) { + for (var i = 0; i < touches.length; i++) { + var touch = touches[i]; + moveHandler(touch); + } + } else { + moveHandler(touches[0]); } e.preventDefault(); }; @@ -346,10 +359,15 @@ * @private */ function touchupHandler(e) { + var elem = $(e.target), data = elem.data(_ns), options = data.options; var touches = e.originalEvent.changedTouches; - for (var i = 0; i < touches.length; i++) { - var touch = touches[i]; - upHandler(touch); + if (options.multitouch) { + for (var i = 0; i < touches.length; i++) { + var touch = touches[i]; + upHandler(touch); + } + } else { + upHandler(touches[0]); } e.preventDefault(); }; diff --git a/jquery.sketchable.min.js b/jquery.sketchable.min.js index 3e8794f..6b58987 100644 --- a/jquery.sketchable.min.js +++ b/jquery.sketchable.min.js @@ -1,5 +1 @@ -/*! - * jQuery sketchable | v1.8 | Luis A. Leiva | MIT license - * A jQuery plugin for the jSketch drawing library. - */ -;(function(j){var g="sketchable";var e={init:function(p){var o=j.extend(true,{},j.fn.sketchable.defaults,p||{});return this.each(function(){var q=j(this),r=q.data(g);if(!r){if(o.interactive){q.bind("mousedown",l);q.bind("mousemove",h);q.bind("mouseup",n);q.bind("touchstart",i);q.bind("touchmove",d);q.bind("touchend",b);this.onselectstart=function(){return false}}}var s=new jSketch(this,o.graphics);s.isDrawing=false;q.data(g,{strokes:[],coords:{},timestamp:(new Date).getTime(),sketch:s,options:o});if(typeof o.events.init==="function"){o.events.init(q,q.data(g))}})},strokes:function(o){if(o){return this.each(function(){var q=j(this),r=q.data(g);r.strokes=o})}else{var p=j(this).data(g);return p.strokes}},handler:function(o){return this.each(function(){var p=j(this),q=p.data(g);o(p,q)})},clear:function(){return this.each(function(){var p=j(this),q=p.data(g),o=q.options;q.sketch.clear();q.strokes=[];q.coords={};if(typeof o.events.clear==="function"){o.events.clear(p,q)}})},reset:function(o){return this.each(function(){var q=j(this),r=q.data(g),p=r.options;q.sketchable("destroy").sketchable(o);if(typeof p.events.reset==="function"){p.events.reset(q,r)}})},destroy:function(){return this.each(function(){var p=j(this),q=p.data(g),o=q.options;if(o.interactive){p.unbind("mouseup",n);p.unbind("mousemove",h);p.unbind("mousedown",l);p.unbind("touchstart",touchHandler);p.unbind("touchmove",touchHandler);p.unbind("touchend",touchHandler)}p.removeData(g);if(typeof o.events.destroy==="function"){o.events.destroy(p,q)}})}};j.fn.sketchable=function(o){if("methods functions hooks".split(" ").indexOf(o)>-1){return e}else{if(e[o]){return e[o].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof o==="object"||!o){return e.init.apply(this,arguments)}else{j.error("Method "+o+' does not exist. See jQuery.sketchable("methods").')}}}return this};j.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 f(p){var o=j(p.target),q=o.offset();return{x:Math.round(p.pageX-q.left),y:Math.round(p.pageY-q.top)}}function c(o,p,r){if(!p.coords[o]){p.coords[o]=[]}var q=(new Date).getTime();if(p.options.relTimestamps){if(p.strokes.length===0&&p.coords[o].length===0){p.timestamp=q}q-=p.timestamp}p.coords[o].push([r.x,r.y,q,+p.sketch.isDrawing])}function l(o){if(o.originalEvent.touches){return false}m(o)}function h(o){if(o.originalEvent.touches){return false}k(o)}function n(o){if(o.originalEvent.touches){return false}a(o)}function i(q){var p=q.originalEvent.changedTouches;for(var o=0;o0){s.sketch.fillCircle(t.x,t.y,q.graphics.firstPointSize)}if(!s.coords[o]){s.coords[o]=[]}if(s.coords[o].length>0){s.strokes.push(s.coords[o]);s.coords[o]=[]}c(o,s,t);if(typeof q.events.mousedown==="function"){q.events.mousedown(r,s,u)}}function k(v){var o=v.identifier||0;var s=j(v.target),t=s.data(g),q=t.options;if((!q.mouseupMovements||t.strokes.length===0)&&!t.sketch.isDrawing){return}var u=f(v);if(t.sketch.isDrawing){var r=t.coords[o][t.coords[o].length-1];t.sketch.beginPath().line(r[0],r[1],u.x,u.y).stroke().closePath()}c(o,t,u);if(typeof q.events.mousemove==="function"){q.events.mousemove(s,t,v)}}function a(s){var o=s.identifier||0;var q=j(s.target),r=q.data(g),p=r.options;r.sketch.isDrawing=false;r.strokes.push(r.coords[o]);r.coords[o]=[];if(typeof p.events.mouseup==="function"){p.events.mouseup(q,r,s)}}})(jQuery); \ No newline at end of file +(function($){var _ns="sketchable";var methods={init:function(opts){var options=$.extend(true,{},$.fn.sketchable.defaults,opts||{});return this.each(function(){var elem=$(this),data=elem.data(_ns);if(!data){if(options.interactive){elem.bind("mousedown",mousedownHandler);elem.bind("mousemove",mousemoveHandler);elem.bind("mouseup",mouseupHandler);elem.bind("touchstart",touchdownHandler);elem.bind("touchmove",touchmoveHandler);elem.bind("touchend",touchupHandler);this.onselectstart=function(){return false}}}var sketch=new jSketch(this,options.graphics);sketch.isDrawing=false;elem.data(_ns,{strokes:[],coords:{},timestamp:(new Date).getTime(),sketch:sketch,options:options});if(typeof options.events.init==="function"){options.events.init(elem,elem.data(_ns))}})},strokes:function(arr){if(arr){return this.each(function(){var elem=$(this),data=elem.data(_ns);data.strokes=arr})}else{var data=$(this).data(_ns);return data.strokes}},handler:function(callback){return this.each(function(){var elem=$(this),data=elem.data(_ns);callback(elem,data)})},clear:function(){return this.each(function(){var elem=$(this),data=elem.data(_ns)||{},options=data.options;if(data.sketch){data.sketch.clear();data.strokes=[];data.coords={}}if(options&&typeof options.events.clear==="function"){options.events.clear(elem,data)}})},reset:function(opts){return this.each(function(){var elem=$(this),data=elem.data(_ns)||{},options=data.options;elem.sketchable("destroy").sketchable(opts);if(options&&typeof options.events.reset==="function"){options.events.reset(elem,data)}})},destroy:function(){return this.each(function(){var elem=$(this),data=elem.data(_ns)||{},options=data.options;if(options.interactive){elem.unbind("mouseup",mouseupHandler);elem.unbind("mousemove",mousemoveHandler);elem.unbind("mousedown",mousedownHandler);elem.unbind("touchstart",touchHandler);elem.unbind("touchmove",touchHandler);elem.unbind("touchend",touchHandler)}elem.removeData(_ns);if(options&&typeof options.events.destroy==="function"){options.events.destroy(elem,data)}})}};$.fn.sketchable=function(method){if("methods functions hooks".split(" ").indexOf(method)>-1){return methods}else if(methods[method]){return methods[method].apply(this,Array.prototype.slice.call(arguments,1))}else if(typeof method==="object"||!method){return methods.init.apply(this,arguments)}else{$.error("Method "+method+' does not exist. See jQuery.sketchable("methods").')}return this};$.fn.sketchable.defaults={interactive:true,mouseupMovements:false,relTimestamps:false,multitouch:true,events:{},graphics:{firstPointSize:3,lineWidth:3,strokeStyle:"#F0F",fillStyle:"#F0F",lineCap:"round",lineJoin:"round",miterLimit:10}};function getMousePos(e){var elem=$(e.target),pos=elem.offset();return{x:Math.round(e.pageX-pos.left),y:Math.round(e.pageY-pos.top)}}function saveMousePos(idx,data,pt){if(!data.coords[idx]){data.coords[idx]=[]}var time=(new Date).getTime();if(data.options.relTimestamps){if(data.strokes.length===0&&data.coords[idx].length===0)data.timestamp=time;time-=data.timestamp}data.coords[idx].push([pt.x,pt.y,time,+data.sketch.isDrawing])}function mousedownHandler(e){if(e.originalEvent.touches)return false;downHandler(e)}function mousemoveHandler(e){if(e.originalEvent.touches)return false;moveHandler(e)}function mouseupHandler(e){if(e.originalEvent.touches)return false;upHandler(e)}function touchdownHandler(e){var elem=$(e.target),data=elem.data(_ns),options=data.options;var touches=e.originalEvent.changedTouches;if(options.multitouch){for(var i=0;i0){data.sketch.fillCircle(p.x,p.y,options.graphics.firstPointSize)}if(!data.coords[idx]){data.coords[idx]=[]}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"){options.events.mousedown(elem,data,e)}}function moveHandler(e){var idx=e.identifier||0;var elem=$(e.target),data=elem.data(_ns),options=data.options;if((!options.mouseupMovements||data.strokes.length===0)&&!data.sketch.isDrawing)return;var p=getMousePos(e);if(data.sketch.isDrawing){var last=data.coords[idx][data.coords[idx].length-1];data.sketch.beginPath().line(last[0],last[1],p.x,p.y).stroke().closePath()}saveMousePos(idx,data,p);if(typeof options.events.mousemove==="function"){options.events.mousemove(elem,data,e)}}function upHandler(e){var idx=e.identifier||0;var elem=$(e.target),data=elem.data(_ns),options=data.options;data.sketch.isDrawing=false;data.strokes.push(data.coords[idx]);data.coords[idx]=[];if(typeof options.events.mouseup==="function"){options.events.mouseup(elem,data,e)}}})(jQuery);