mirror of https://github.com/luileito/jsketch.git
Refactorization
This commit is contained in:
parent
4653df6c23
commit
ff1e7c82b4
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
!function(a){function b(b){function c(){if(h>0){h--;var a=new Image;a.src=g[h].image,a.onload=function(){e(this)}}}function d(){if(h<g.length-1){h++;var a=new Image;a.src=g[h].image,a.onload=function(){e(this)}}}function e(a){b.sketchable("handler",function(b,c){c.sketch.clear(),c.sketch.graphics.drawImage(a,0,0),c.strokes=g[h].strokes.slice()})}function f(a){if(a.ctrlKey)switch(a.which){case 26:a.shiftKey?i.redo():i.undo();break;case 25:i.redo()}}var g=[],h=-1,i=this;this.undo=function(){return c(),this},this.redo=function(){return d(),this},this.reset=function(){return g=[],h=-1,this},this.save=function(a){return b.sketchable("handler",function(b,c){a&&a.identifier>0?g[h].strokes=c.strokes.slice():(g.push({image:b[0].toDataURL(),strokes:c.strokes.slice()}),h++)}),this},this.init=function(){return a(document).off("keypress",f),a(document).on("keypress",f),this},this.destroy=function(){return a(document).off("keypress",f),this.reset()}}var c="sketchable";a.fn.sketchable.plugins.memento=function(d){function e(a){if(!f.options[a+"$bound"])if(f.options[a+"$bound"]=!0,f.options.events&&"function"==typeof f.options.events[a]){var b=f.options.events[a];f.options.events[a]=function(){b.apply(d,arguments),g[a].apply(d,arguments)}}else f.options.events[a]=g[a]}for(var f=d.sketchable("config"),g={clear:function(a,b){b.memento.reset().save()},mouseup:function(a,b,c){b.memento.save(c)},destroy:function(a,b){b.memento.destroy()}},h="mouseup clear destroy".split(" "),i=0;i<h.length;i++)e(h[i]);a.extend(a.fn.sketchable.api,{undo:function(){var b=a(this),d=b.data(c);d.memento.undo()},redo:function(){var b=a(this),d=b.data(c);d.memento.redo()},save:function(){var b=a(this),d=b.data(c);d.memento.save()}}),f.memento=new b(d),f.memento.init().save()}}(jQuery);
|
||||
!function(a){function b(b){function c(a,c){b.sketchable("handler",function(b,d){d.sketch.clear(),d.sketch.graphics.drawImage(a,0,0),d.strokes=c.slice()})}function d(a){if(a.ctrlKey)switch(a.which){case 26:a.shiftKey?g.redo():g.undo();break;case 25:g.redo()}}var e=[],f=-1,g=this;this.undo=function(){return f>0&&(f--,this.restore()),this},this.redo=function(){return f<e.length-1&&(f++,this.restore()),this},this.reset=function(){return e=[],f=-1,this.save()},this.save=function(a){return b.sketchable("handler",function(b,c){a&&a.identifier>0?e[f].strokes=c.strokes.slice():(e.push({image:b[0].toDataURL(),strokes:c.strokes.slice()}),f++)}),this},this.state=function(){return JSON.parse(JSON.stringify(e[f]))},this.restore=function(a){a||(a=e[f]);var b=new Image;b.src=a.image,b.onload=function(){c(this,a.strokes)}},this.init=function(){return a(document).off("keypress",d),a(document).on("keypress",d),this.save()},this.destroy=function(){return a(document).off("keypress",d),this.reset()}}var c="sketchable";a.fn.sketchable.plugins.memento=function(d){function e(a){if(!f.options["_bound$"+a])if(f.options["_bound$"+a]=!0,f.options.events&&"function"==typeof f.options.events[a]){var b=f.options.events[a];f.options.events[a]=function(){b.apply(d,arguments),g[a].apply(d,arguments)}}else f.options.events[a]=g[a]}for(var f=d.sketchable("config"),g={clear:function(a,b){b.memento.reset()},mouseup:function(a,b,c){b.memento.save(c)},destroy:function(a,b){b.memento.destroy()}},h="mouseup clear destroy".split(" "),i=0;i<h.length;i++)e(h[i]);a.extend(a.fn.sketchable.api,{memento:{undo:function(){var b=a(this).data(c);return b.memento.undo()},redo:function(){var b=a(this).data(c);return b.memento.redo()},save:function(){var b=a(this).data(c);return b.memento.save()},state:function(){var b=a(this).data(c);return b.memento.state()},restore:function(b){var d=a(this).data(c);return d.memento.restore(b)}}}),f.memento=new b(d),f.memento.init()}}(jQuery);
|
||||
|
|
@ -1 +1 @@
|
|||
!function(a){function b(a,b){b||(b=a.data(o).options),b.cssCursors&&(a[0].style.cursor=b.interactive?"pointer":"not-allowed"),this.onselectstart=function(){return!1}}function c(b){var c=a(b.target),d=c.offset();return{x:Math.round(b.pageX-d.left),y:Math.round(b.pageY-d.top)}}function d(a,b,c){b.coords[a]||(b.coords[a]=[]);var d=b.coords[a],e=(new Date).getTime();if(b.options.relTimestamps&&(0===b.strokes.length&&0===d.length&&(b.timestamp=e),e-=b.timestamp),d.push([c.x,c.y,e,+b.sketch.isDrawing]),b.options.filterCoords&&d.length>1){var f=d.length-1,g=d[f],h=d[f-1];g[0]==h[0]&&g[1]==h[1]&&d.splice(f,1)}}function e(a){return a.originalEvent.touches?!1:void l(a)}function f(a){return a.originalEvent.touches?!1:void m(a)}function g(a){return a.originalEvent.touches?!1:void n(a)}function h(b,c){var d=a(b.target),e=d.data(o),f=e.options;if(f.multitouch)for(var g=b.originalEvent.changedTouches,h=0;h<g.length;h++){var i=g[h];i.type=b.type,i.identifier=h,c(i)}else{var i=b.originalEvent.touches[0];i.type=b.type,i.identifier=0,c(i)}}function i(a){h(a,l),a.preventDefault()}function j(a){h(a,m),a.preventDefault()}function k(a){h(a,n),a.preventDefault()}function l(b){if(3===b.which)return!1;var e=b.identifier||0,f=a(b.target),g=f.data(o),h=g.options;if(h.interactive){g.sketch.isDrawing=!0;var i=c(b);h.graphics.firstPointSize>0&&g.sketch.beginFill(h.graphics.fillStyle).fillCircle(i.x,i.y,h.graphics.firstPointSize).endFill(),g.coords[e]||(g.coords[e]=[]),g.coords[e].length>0&&(g.strokes.push(g.coords[e]),g.coords[e]=[]),d(e,g,i),"function"==typeof h.events.mousedown&&h.events.mousedown(f,g,b)}}function m(b){var e=b.identifier||0,f=a(b.target),g=f.data(o),h=g.options;if(h.interactive&&(h.mouseupMovements&&0!==g.strokes.length||g.sketch.isDrawing)){var i=c(b);if(g.sketch.isDrawing){var j=g.coords[e][g.coords[e].length-1];g.sketch.beginPath().line(j[0],j[1],i.x,i.y).stroke().closePath()}d(e,g,i),"function"==typeof h.events.mousemove&&h.events.mousemove(f,g,b)}}function n(b){var c=b.identifier||0,d=a(b.target),e=d.data(o),f=e.options;f.interactive&&(e.sketch.isDrawing=!1,e.strokes.push(e.coords[c]),e.coords[c]=[],"function"==typeof f.events.mouseup&&f.events.mouseup(d,e,b))}var o="sketchable",p={init:function(c){var d=a.extend(!0,{},a.fn.sketchable.defaults,c||{});return this.each(function(){var c=a(this),h=c.data(o);h||(c.bind("mousedown",e),c.bind("mousemove",f),c.bind("mouseup",g),c.bind("touchstart",i),c.bind("touchmove",j),c.bind("touchend",k),b(c,d));var l=new jSketch(this,d.graphics);c.data(o,{strokes:[],coords:{},timestamp:(new Date).getTime(),sketch:l,options:d}),d.events&&"function"==typeof d.events.init&&d.events.init(c,c.data(o));for(var m in a.fn.sketchable.plugins)a.fn.sketchable.plugins[m](c)})},config:function(c){return c?this.each(function(){var d=a(this),e=d.data(o);e.options=a.extend(!0,{},a.fn.sketchable.defaults,e.options,c),b(d)}):a(this).data(o)},strokes:function(b){if(b)return this.each(function(){var c=a(this),d=c.data(o);d.strokes=b});var c=a(this).data(o);return c.strokes},handler:function(b){return this.each(function(){var c=a(this),d=c.data(o);b(c,d)})},clear:function(){return this.each(function(){var b=a(this),c=b.data(o)||{},d=c.options;c.sketch&&(c.sketch.clear(),c.strokes=[],c.coords={}),d&&"function"==typeof d.events.clear&&d.events.clear(b,c)})},reset:function(b){return this.each(function(){var c=a(this),d=c.data(o)||{},e=d.options;c.sketchable("destroy").sketchable(b),e&&"function"==typeof e.events.reset&&e.events.reset(c,d)})},destroy:function(){return this.each(function(){var b=a(this),c=b.data(o)||{},d=c.options;b.unbind("mouseup",g),b.unbind("mousemove",f),b.unbind("mousedown",e),b.unbind("touchstart",i),b.unbind("touchmove",j),b.unbind("touchend",k),b.removeData(o),d&&"function"==typeof d.events.destroy&&d.events.destroy(b,c)})}};a.fn.sketchable=function(b){return"object"!=typeof b&&b?p[b]?p[b].apply(this,Array.prototype.slice.call(arguments,1)):(a.error("Unknown method: "+b),this):p.init.apply(this,arguments)},a.fn.sketchable.api=p,a.fn.sketchable.plugins={},a.fn.sketchable.defaults={interactive:!0,mouseupMovements:!1,relTimestamps:!1,multitouch:!0,cssCursors:!0,filterCoords:!1,events:{},graphics:{firstPointSize:3,lineWidth:3,strokeStyle:"#F0F",fillStyle:"#F0F",lineCap:"round",lineJoin:"round",miterLimit:10}}}(jQuery);
|
||||
!function(a){function b(a,b){b||(b=a.data(p).options),b.cssCursors&&(a[0].style.cursor=b.interactive?"pointer":"not-allowed"),this.onselectstart=function(){return!1}}function c(a,b){b=b.split(".");for(var c=0;c<b.length;c++){var d=b[c];a=a[d]}return a}function d(b){var c=a(b.target),d=c.offset();return{x:Math.round(b.pageX-d.left),y:Math.round(b.pageY-d.top)}}function e(a,b,c){var d=b.coords[a],e=(new Date).getTime();if(b.options.relTimestamps&&(0===b.strokes.length&&0===d.length&&(b.timestamp=e),e-=b.timestamp),d.push([c.x,c.y,e,+b.sketch.isDrawing]),b.options.filterCoords&&d.length>1){var f=d.length-1,g=d[f],h=d[f-1];g[0]==h[0]&&g[1]==h[1]&&d.splice(f,1)}}function f(a){return a.originalEvent.touches?!1:void l(a)}function g(a){return a.originalEvent.touches?!1:void m(a)}function h(a){return a.originalEvent.touches?!1:void n(a)}function i(a){o(a,l),a.preventDefault()}function j(a){o(a,m),a.preventDefault()}function k(a){o(a,n),a.preventDefault()}function l(b){if(3===b.which)return!1;var c=b.identifier||0,f=a(b.target),g=f.data(p),h=g.options;if(h.interactive){g.sketch.isDrawing=!0;var i=d(b);h.graphics.firstPointSize>0&&g.sketch.beginFill(h.graphics.fillStyle).fillCircle(i.x,i.y,h.graphics.firstPointSize).endFill();var j=g.coords[c];j||(j=[]),j.length>0&&g.strokes.push(j),g.coords[c]=[],e(c,g,i),"function"==typeof h.events.mousedown&&h.events.mousedown(f,g,b)}}function m(b){var c=b.identifier||0,f=a(b.target),g=f.data(p),h=g.options;if(h.interactive&&(h.mouseupMovements&&0!==g.strokes.length||g.sketch.isDrawing)){var i=d(b),j=g.coords[c],k=j[j.length-1];if(k){var l=g.sketch.beginPath();g.sketch.isDrawing?l.lineStyle(h.graphics.strokeStyle,h.graphics.lineWidth):h.mouseupMovements.visible!==!1&&l.lineStyle(h.mouseupMovements.strokeStyle||"#DDD",h.mouseupMovements.lineWidth||1),l.line(k[0],k[1],i.x,i.y).stroke().closePath()}e(c,g,i),"function"==typeof h.events.mousemove&&h.events.mousemove(f,g,b)}}function n(b){var c=b.identifier||0,d=a(b.target),e=d.data(p),f=e.options;f.interactive&&(e.sketch.isDrawing=!1,e.strokes.push(e.coords[c]),e.coords[c]=[],"function"==typeof f.events.mouseup&&f.events.mouseup(d,e,b))}function o(b,c){var d=a(b.target),e=d.data(p),f=e.options;if(f.multitouch)for(var g=b.originalEvent.changedTouches,h=0;h<g.length;h++){var i=g[h];i.type=b.type,i.identifier=h,c(i)}else{var i=b.originalEvent.touches[0];i.type=b.type,i.identifier=0,c(i)}}var p="sketchable",q={init:function(c){var d=a.extend(!0,{},a.fn.sketchable.defaults,c||{});return this.each(function(){var c=a(this),e=c.data(p);e||(c.bind("mousedown",f),c.bind("mousemove",g),c.bind("mouseup",h),c.bind("touchstart",i),c.bind("touchmove",j),c.bind("touchend",k),b(c,d));var l=new jSketch(this,d.graphics);c.data(p,{strokes:[],coords:{},timestamp:(new Date).getTime(),sketch:l,options:d}),d.events&&"function"==typeof d.events.init&&d.events.init(c,c.data(p));for(var m in a.fn.sketchable.plugins)a.fn.sketchable.plugins[m](c)})},config:function(c){return c?this.each(function(){var d=a(this),e=d.data(p);e.options=a.extend(!0,{},a.fn.sketchable.defaults,e.options,c),b(d)}):a(this).data(p)},strokes:function(b){if(b)return this.each(function(){var c=a(this),d=c.data(p);d.strokes=b});var c=a(this).data(p);return c.strokes},handler:function(b){return this.each(function(){var c=a(this),d=c.data(p);b(c,d)})},clear:function(){return this.each(function(){var b=a(this),c=b.data(p)||{},d=c.options;c.sketch&&(c.sketch.clear(),c.strokes=[],c.coords={}),d&&"function"==typeof d.events.clear&&d.events.clear(b,c)})},reset:function(b){return this.each(function(){var c=a(this),d=c.data(p)||{},e=d.options;c.sketchable("destroy").sketchable(b),e&&"function"==typeof e.events.reset&&e.events.reset(c,d)})},destroy:function(){return this.each(function(){var b=a(this),c=b.data(p)||{},d=c.options;b.unbind("mouseup",h),b.unbind("mousemove",g),b.unbind("mousedown",f),b.unbind("touchstart",i),b.unbind("touchmove",j),b.unbind("touchend",k),b.removeData(p),d&&"function"==typeof d.events.destroy&&d.events.destroy(b,c)})}};a.fn.sketchable=function(b){var d=Array.prototype.slice.call(arguments,1);if("object"==typeof b||!b)return q.init.apply(this,arguments);if(b.indexOf(".")>-1){var e=c(q,b);return e.apply(this,d)}return q[b]?q[b].apply(this,d):(a.error("Unknown method: "+b),this)},a.fn.sketchable.api=q,a.fn.sketchable.plugins={},a.fn.sketchable.defaults={interactive:!0,mouseupMovements:!1,relTimestamps:!1,multitouch:!0,cssCursors:!0,filterCoords:!1,events:{},graphics:{firstPointSize:3,lineWidth:3,strokeStyle:"#F0F",fillStyle:"#F0F",lineCap:"round",lineJoin:"round",miterLimit:10}}}(jQuery);
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
!function(a){function b(a){function b(){if(g>0){g--;var a=new Image;a.src=f[g].image,a.onload=function(){d(this)}}}function c(){if(g<f.length-1){g++;var a=new Image;a.src=f[g].image,a.onload=function(){d(this)}}}function d(b){a.handler(function(a,c){c.sketch.clear(),c.sketch.graphics.drawImage(b,0,0),c.strokes=f[g].strokes.slice()})}function e(a){if(a.ctrlKey)switch(a.which){case 26:a.shiftKey?h.redo():h.undo();break;case 25:h.redo()}}var f=[],g=-1,h=this;this.undo=function(){return b(),this},this.redo=function(){return c(),this},this.reset=function(){return f=[],g=-1,this},this.save=function(b){return a.handler(function(a,c){b&&b.identifier>0?f[g].strokes=c.strokes.slice():(f.push({image:a.toDataURL(),strokes:c.strokes.slice()}),g++)}),this},this.init=function(){return Event.remove(document,"keypress",e),Event.add(document,"keypress",e),this},this.destroy=function(){return Event.remove(document,"keypress",e),this.reset()}}var c="sketchable";Sketchable.prototype.plugins.memento=function(a){function d(b){if(!e.options[b+"$bound"])if(e.options[b+"$bound"]=!0,e.options.events&&"function"==typeof e.options.events[b]){var c=e.options.events[b];e.options.events[b]=function(){c.apply(a,arguments),f[b].apply(a,arguments)}}else e.options.events[b]=f[b]}for(var e=a.config(),f={clear:function(a,b){b.memento.reset().save()},mouseup:function(a,b,c){b.memento.save(c)},destroy:function(a,b){b.memento.destroy()}},g="mouseup clear destroy".split(" "),h=0;h<g.length;h++)d(g[h]);deepExtend(Sketchable.prototype,{undo:function(){var a=this.elem,b=dataBind(a)[c];b.memento.undo()},redo:function(){var a=this.elem,b=dataBind(a)[c];b.memento.redo()},save:function(){var a=this.elem,b=dataBind(a)[c];b.memento.save()}}),e.memento=new b(a),e.memento.init().save()}}(this);
|
||||
!function(a){function b(a){function b(b,c){a.handler(function(a,d){d.sketch.clear(),d.sketch.graphics.drawImage(b,0,0),d.strokes=c.slice()})}function c(a){if(a.ctrlKey)switch(a.which){case 26:a.shiftKey?f.redo():f.undo();break;case 25:f.redo()}}var d=[],e=-1,f=this;this.undo=function(){return e>0&&(e--,this.restore()),this},this.redo=function(){return e<d.length-1&&(e++,this.restore()),this},this.reset=function(){return d=[],e=-1,this.save()},this.save=function(b){return a.handler(function(a,c){b&&b.identifier>0?d[e].strokes=c.strokes.slice():(d.push({image:a.toDataURL(),strokes:c.strokes.slice()}),e++)}),this},this.state=function(){return JSON.parse(JSON.stringify(d[e]))},this.restore=function(a){a||(a=d[e]);var c=new Image;c.src=a.image,c.onload=function(){b(this,a.strokes)}},this.init=function(){return Event.remove(document,"keypress",c),Event.add(document,"keypress",c),this.save()},this.destroy=function(){return Event.remove(document,"keypress",c),this.reset()}}var c="sketchable";Sketchable.prototype.plugins.memento=function(a){function d(b){if(!e.options["_bound$"+b])if(e.options["_bound$"+b]=!0,e.options.events&&"function"==typeof e.options.events[b]){var c=e.options.events[b];e.options.events[b]=function(){c.apply(a,arguments),f[b].apply(a,arguments)}}else e.options.events[b]=f[b]}for(var e=a.config(),f={clear:function(a,b){b.memento.reset()},mouseup:function(a,b,c){b.memento.save(c)},destroy:function(a,b){b.memento.destroy()}},g="mouseup clear destroy".split(" "),h=0;h<g.length;h++)d(g[h]);deepExtend(a,{memento:{undo:function(){var b=dataBind(a.elem)[c];return b.memento.undo()},redo:function(){var b=dataBind(a.elem)[c];return b.memento.redo()},save:function(){var b=dataBind(a.elem)[c];return b.memento.save()},state:function(){var b=dataBind(a.elem)[c];return b.memento.state()},restore:function(b){var d=dataBind(a.elem)[c];return d.memento.restore(b)}}}),e.memento=new b(a),e.memento.init()}}(this);
|
||||
|
|
@ -1 +1 @@
|
|||
!function(a){function b(a,b){if(!a)throw new Error("Sketchable requires a DOM element.");return"string"==typeof a&&(a=r.querySelector(a)),this.elem=a,this.init(b)}function c(b){var c=b.getBoundingClientRect(),d=r.body,e=r.documentElement,f=a.pageYOffset||e.scrollTop||d.scrollTop,g=a.pageXOffset||e.scrollLeft||d.scrollLeft,h=e.clientTop||d.clientTop||0,i=e.clientLeft||d.clientLeft||0,j=c.top+f-h,k=c.left+g-i;return{top:Math.round(j),left:Math.round(k)}}function d(a,b){b||(b=dataBind(a)[q].options),b.cssCursors&&(a.style.cursor=b.interactive?"pointer":"not-allowed"),a.onselectstart=function(){return!1}}function e(a){var b=a.target,d=c(b);return{x:Math.round(a.pageX-d.left),y:Math.round(a.pageY-d.top)}}function f(a,b,c){b.coords[a]||(b.coords[a]=[]);var d=b.coords[a],e=(new Date).getTime();if(b.options.relTimestamps&&(0===b.strokes.length&&0===d.length&&(b.timestamp=e),e-=b.timestamp),d.push([c.x,c.y,e,+b.sketch.isDrawing]),b.options.filterCoords&&d.length>1){var f=d.length-1,g=d[f],h=d[f-1];g[0]==h[0]&&g[1]==h[1]&&d.splice(f,1)}}function g(a){return a.touches?!1:void n(a)}function h(a){return a.touches?!1:void o(a)}function i(a){return a.touches?!1:void p(a)}function j(a,b){var c=a.target,d=dataBind(c)[q],e=d.options;if(e.multitouch)for(var f=a.changedTouches,g=0;g<f.length;g++){var h=f[g];h.type=a.type,h.identifier=g,b(h)}else{var h=a.touches[0];h.type=a.type,h.identifier=0,b(h)}a.preventDefault()}function k(a){j(a,n),a.preventDefault()}function l(a){j(a,o),a.preventDefault()}function m(a){j(a,p),a.preventDefault()}function n(a){if(Event.isRightClick(a))return!1;var b=a.identifier||0,c=a.target,d=dataBind(c)[q],g=d.options;if(g.interactive){d.sketch.isDrawing=!0;var h=e(a);g.graphics.firstPointSize>0&&d.sketch.beginFill(g.graphics.fillStyle).fillCircle(h.x,h.y,g.graphics.firstPointSize).endFill(),d.coords[b]&&d.coords[b].length>0&&(d.strokes.push(d.coords[b].slice()),d.coords[b]=[]),f(b,d,h),"function"==typeof g.events.mousedown&&g.events.mousedown(c,d,a)}}function o(a){var b=a.identifier||0,c=a.target,d=dataBind(c)[q],g=d.options;if(g.interactive&&(g.mouseupMovements&&0!==d.strokes.length||d.sketch.isDrawing)){var h=e(a);if(d.sketch.isDrawing){var i=d.coords[b][d.coords[b].length-1];d.sketch.beginPath().line(i[0],i[1],h.x,h.y).stroke().closePath()}f(b,d,h),"function"==typeof g.events.mousemove&&g.events.mousemove(c,d,a)}}function p(a){var b=a.identifier||0,c=a.target,d=dataBind(c)[q],e=d.options;e.interactive&&(d.sketch.isDrawing=!1,d.strokes.push(d.coords[b].slice()),d.coords[b]=[],"function"==typeof e.events.mouseup&&e.events.mouseup(c,d,a))}var q="sketchable",r=a.document;b.prototype={init:function(a){var a=deepExtend({},b.prototype.defaults,a||{}),c=this.elem,e=dataBind(c)[q];e||(Event.add(c,"mousedown",g),Event.add(c,"mousemove",h),Event.add(c,"mouseup",i),Event.add(c,"touchstart",k),Event.add(c,"touchmove",l),Event.add(c,"touchend",m),d(c,a));var f=new jSketch(c,a.graphics);dataBind(c)[q]=e={strokes:[],coords:{},timestamp:(new Date).getTime(),sketch:f,options:a},"function"==typeof a.events.init&&a.events.init(c,e);for(var j in this.plugins)this.plugins[j](this);return this},config:function(a){var c=this.elem,e=dataBind(c)[q];return a?(e.options=deepExtend({},b.prototype.defaults,a||{}),d(c),this):e},strokes:function(a){var b=this.elem;if(a){var c=dataBind(b)[q];return c.strokes=a,this}var c=dataBind(b)[q];return c.strokes},handler:function(a){var b=this.elem,c=dataBind(b)[q];return a(b,c),this},clear:function(){var a=this.elem,b=dataBind(a)[q],c=b.options;return b.sketch.clear(),b.strokes=[],b.coords={},"function"==typeof c.events.clear&&c.events.clear(a,b),this},reset:function(a){var b=this.elem,c=dataBind(b)[q],a=c.options;return this.destroy().init(a),"function"==typeof a.events.reset&&a.events.reset(b,c),this},destroy:function(){var a=this.elem,b=dataBind(a)[q],c=b.options;return Event.remove(a,"mouseup",i),Event.remove(a,"mousemove",h),Event.remove(a,"mousedown",g),Event.remove(a,"touchstart",k),Event.remove(a,"touchmove",l),Event.remove(a,"touchend",m),dataBind(a)[q]=null,"function"==typeof c.events.destroy&&c.events.destroy(a,b),this}},b.prototype.plugins={},b.prototype.defaults={interactive:!0,mouseupMovements:!1,relTimestamps:!1,multitouch:!0,cssCursors:!0,filterCoords:!1,events:{},graphics:{firstPointSize:3,lineWidth:3,strokeStyle:"#F0F",fillStyle:"#F0F",lineCap:"round",lineJoin:"round",miterLimit:10}},a.Sketchable=b}(this);
|
||||
!function(a){function b(a,b){if(!a)throw new Error("Sketchable requires a DOM element.");return"string"==typeof a&&(a=r.querySelector(a)),this.elem=a,this.init(b)}function c(b){var c=b.getBoundingClientRect(),d=r.body,e=r.documentElement,f=a.pageYOffset||e.scrollTop||d.scrollTop,g=a.pageXOffset||e.scrollLeft||d.scrollLeft,h=e.clientTop||d.clientTop||0,i=e.clientLeft||d.clientLeft||0,j=c.top+f-h,k=c.left+g-i;return{top:Math.round(j),left:Math.round(k)}}function d(a,b){b||(b=dataBind(a)[q].options),b.cssCursors&&(a.style.cursor=b.interactive?"pointer":"not-allowed"),a.onselectstart=function(){return!1}}function e(a){var b=a.target,d=c(b);return{x:Math.round(a.pageX-d.left),y:Math.round(a.pageY-d.top)}}function f(a,b,c){var d=b.coords[a],e=(new Date).getTime();if(b.options.relTimestamps&&(0===b.strokes.length&&0===d.length&&(b.timestamp=e),e-=b.timestamp),d.push([c.x,c.y,e,+b.sketch.isDrawing]),b.options.filterCoords&&d.length>1){var f=d.length-1,g=d[f],h=d[f-1];g[0]==h[0]&&g[1]==h[1]&&d.splice(f,1)}}function g(a){return a.touches?!1:void m(a)}function h(a){return a.touches?!1:void n(a)}function i(a){return a.touches?!1:void o(a)}function j(a){p(a,m),a.preventDefault()}function k(a){p(a,n),a.preventDefault()}function l(a){p(a,o),a.preventDefault()}function m(a){if(Event.isRightClick(a))return!1;var b=a.identifier||0,c=a.target,d=dataBind(c)[q],g=d.options;if(g.interactive){d.sketch.isDrawing=!0;var h=e(a);g.graphics.firstPointSize>0&&d.sketch.beginFill(g.graphics.fillStyle).fillCircle(h.x,h.y,g.graphics.firstPointSize).endFill();var i=d.coords[b];i||(i=[]),i.length>0&&d.strokes.push(i),d.coords[b]=[],f(b,d,h),"function"==typeof g.events.mousedown&&g.events.mousedown(c,d,a)}}function n(a){var b=a.identifier||0;if(elem=a.target,data=dataBind(elem)[q],options=data.options,options.interactive&&(options.mouseupMovements&&0!==data.strokes.length||data.sketch.isDrawing)){var c=e(a),d=data.coords[b],g=d[d.length-1];if(g){var h=data.sketch.beginPath();data.sketch.isDrawing?h.lineStyle(options.graphics.strokeStyle,options.graphics.lineWidth):options.mouseupMovements.visible!==!1&&h.lineStyle(options.mouseupMovements.strokeStyle||"#DDD",options.mouseupMovements.lineWidth||1),h.line(g[0],g[1],c.x,c.y).stroke().closePath()}f(b,data,c),"function"==typeof options.events.mousemove&&options.events.mousemove(elem,data,a)}}function o(a){var b=a.identifier||0;elem=a.target,data=dataBind(elem)[q],options=data.options,options.interactive&&(data.sketch.isDrawing=!1,data.strokes.push(data.coords[b]),data.coords[b]=[],"function"==typeof options.events.mouseup&&options.events.mouseup(elem,data,a))}function p(a,b){var c=a.target,d=dataBind(c)[q],e=d.options;if(e.multitouch)for(var f=a.changedTouches,g=0;g<f.length;g++){var h=f[g];h.type=a.type,h.identifier=g,b(h)}else{var h=a.touches[0];h.type=a.type,h.identifier=0,b(h)}a.preventDefault()}var q="sketchable",r=a.document;b.prototype={init:function(a){var a=deepExtend({},b.prototype.defaults,a||{}),c=this.elem,e=dataBind(c)[q];e||(Event.add(c,"mousedown",g),Event.add(c,"mousemove",h),Event.add(c,"mouseup",i),Event.add(c,"touchstart",j),Event.add(c,"touchmove",k),Event.add(c,"touchend",l),d(c,a));var f=new jSketch(c,a.graphics);dataBind(c)[q]=e={strokes:[],coords:{},timestamp:(new Date).getTime(),sketch:f,instance:this,options:a},"function"==typeof a.events.init&&a.events.init(c,e);for(var m in this.plugins)this.plugins[m](this);return this},config:function(a){var c=this.elem,e=dataBind(c)[q];return a?(e.options=deepExtend({},b.prototype.defaults,e.options,a),d(c),this):e},strokes:function(a){var b=this.elem;if(a){var c=dataBind(b)[q];return c.strokes=a,this}var c=dataBind(b)[q];return c.strokes},handler:function(a){var b=this.elem,c=dataBind(b)[q];return a(b,c),this},clear:function(){var a=this.elem,b=dataBind(a)[q],c=b.options;return b.sketch.clear(),b.strokes=[],b.coords={},"function"==typeof c.events.clear&&c.events.clear(a,b),this},reset:function(a){var b=this.elem,c=dataBind(b)[q],a=c.options;return this.destroy().init(a),"function"==typeof a.events.reset&&a.events.reset(b,c),this},destroy:function(){var a=this.elem,b=dataBind(a)[q],c=b.options;return Event.remove(a,"mouseup",i),Event.remove(a,"mousemove",h),Event.remove(a,"mousedown",g),Event.remove(a,"touchstart",j),Event.remove(a,"touchmove",k),Event.remove(a,"touchend",l),dataBind(a)[q]=null,"function"==typeof c.events.destroy&&c.events.destroy(a,b),this}},b.prototype.plugins={},b.prototype.defaults={interactive:!0,mouseupMovements:!1,relTimestamps:!1,multitouch:!0,cssCursors:!0,filterCoords:!1,events:{},graphics:{firstPointSize:3,lineWidth:3,strokeStyle:"#F0F",fillStyle:"#F0F",lineCap:"round",lineJoin:"round",miterLimit:10}},a.Sketchable=b}(this);
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* jQuery sketchable | v2.0 | Luis A. Leiva | MIT license
|
||||
* jQuery sketchable | v2.1 | Luis A. Leiva | MIT license
|
||||
* A jQuery plugin for the jSketch drawing library.
|
||||
*/
|
||||
|
||||
|
|
@ -15,13 +15,14 @@
|
|||
*/
|
||||
|
||||
/* eslint-env browser */
|
||||
/* global jQuery */
|
||||
;(function($) {
|
||||
|
||||
// Custom namespace ID, for private data bindind.
|
||||
var namespace = 'sketchable';
|
||||
|
||||
// Begin jQuery Sketchable plugin API.
|
||||
var methods = {
|
||||
var api = {
|
||||
/**
|
||||
* Initialize the selected jQuery objects.
|
||||
* @param {Object} [options] - Configuration (default: {@link $.fn.sketchable.defaults}).
|
||||
|
|
@ -217,7 +218,7 @@
|
|||
* @namespace $.fn.sketchable
|
||||
* @param {String|Object} method - Method to invoke, or a configuration object.
|
||||
* @return jQuery
|
||||
* @version 1.9
|
||||
* @version 2.1
|
||||
* @author Luis A. Leiva
|
||||
* @license MIT license
|
||||
* @example
|
||||
|
|
@ -225,10 +226,17 @@
|
|||
* $('canvas').sketchable({ interactive:false });
|
||||
*/
|
||||
$.fn.sketchable = function(method) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (typeof method === 'object' || !method) {
|
||||
return methods.init.apply(this, arguments);
|
||||
} else if (methods[method]) {
|
||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
// Constructor.
|
||||
return api.init.apply(this, arguments);
|
||||
} else if (method.indexOf('.') > -1) {
|
||||
// Plugin method.
|
||||
var actualMethod = locate(api, method);
|
||||
return actualMethod.apply(this, args);
|
||||
} else if (api[method]) {
|
||||
// Instance method.
|
||||
return api[method].apply(this, args);
|
||||
} else {
|
||||
$.error('Unknown method: ' + method);
|
||||
}
|
||||
|
|
@ -242,7 +250,7 @@
|
|||
* @type {Object}
|
||||
* @see Sketchable.prototype
|
||||
*/
|
||||
$.fn.sketchable.api = methods;
|
||||
$.fn.sketchable.api = api;
|
||||
|
||||
/**
|
||||
* Plugins store.
|
||||
|
|
@ -263,11 +271,11 @@
|
|||
* @type {Object}
|
||||
* @example
|
||||
* // The following is the default configuration:
|
||||
* new Sketchable('canvas', {
|
||||
* $('canvas').sketchable({
|
||||
* interactive: true,
|
||||
* mouseupMovements: false,
|
||||
* relTimestamps: false,
|
||||
* multitouch: false,
|
||||
* multitouch: true,
|
||||
* cssCursors: true,
|
||||
* filterCoords: false,
|
||||
* // Event hooks.
|
||||
|
|
@ -353,6 +361,18 @@
|
|||
this.onselectstart = function() { return false };
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function locate(obj, path) {
|
||||
path = path.split('.');
|
||||
for (var i = 0; i < path.length; i++) {
|
||||
var key = path[i];
|
||||
obj = obj[key];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
|
@ -368,11 +388,7 @@
|
|||
* @private
|
||||
*/
|
||||
function saveMousePos(idx, data, pt) {
|
||||
// Ensure that coords is properly initialized.
|
||||
if (!data.coords[idx]) {
|
||||
data.coords[idx] = [];
|
||||
}
|
||||
// Use pointer for easy handling.
|
||||
// Current coords are already initialized.
|
||||
var coords = data.coords[idx];
|
||||
|
||||
var time = (new Date).getTime();
|
||||
|
|
@ -420,30 +436,6 @@
|
|||
upHandler(e);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function execTouchEvent(e, callback) {
|
||||
var elem = $(e.target), data = elem.data(namespace), options = data.options;
|
||||
if (options.multitouch) {
|
||||
// Track all fingers.
|
||||
var touches = e.originalEvent.changedTouches;
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
var touch = touches[i];
|
||||
// Add event type and finger ID.
|
||||
touch.type = e.type;
|
||||
touch.identifier = i;
|
||||
callback(touch);
|
||||
}
|
||||
} else {
|
||||
// Track only the current finger.
|
||||
var touch = e.originalEvent.touches[0];
|
||||
touch.type = e.type;
|
||||
touch.identifier = 0;
|
||||
callback(touch);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
|
@ -483,20 +475,21 @@
|
|||
if (!options.interactive) return;
|
||||
|
||||
data.sketch.isDrawing = true;
|
||||
|
||||
var p = getMousePos(e);
|
||||
// Mark visually 1st point of stroke.
|
||||
if (options.graphics.firstPointSize > 0) {
|
||||
data.sketch.beginFill(options.graphics.fillStyle).fillCircle(p.x, p.y, options.graphics.firstPointSize).endFill();
|
||||
}
|
||||
|
||||
// Ensure that coords is properly initialized.
|
||||
if (!data.coords[idx]) {
|
||||
data.coords[idx] = [];
|
||||
}
|
||||
var coords = data.coords[idx];
|
||||
if (!coords) coords = [];
|
||||
// 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] = [];
|
||||
}
|
||||
if (coords.length > 0) data.strokes.push(coords);
|
||||
// In any case, ensure that coords is properly reset/initialized.
|
||||
data.coords[idx] = [];
|
||||
|
||||
saveMousePos(idx, data, p);
|
||||
|
||||
if (typeof options.events.mousedown === 'function') {
|
||||
|
|
@ -508,20 +501,31 @@
|
|||
* @private
|
||||
*/
|
||||
function moveHandler(e) {
|
||||
var idx = e.identifier || 0;
|
||||
var elem = $(e.target), data = elem.data(namespace), options = data.options;
|
||||
|
||||
var idx = e.identifier || 0,
|
||||
elem = $(e.target),
|
||||
data = elem.data(namespace),
|
||||
options = data.options;
|
||||
// Exit early if interactivity is disabled.
|
||||
if (!options.interactive) return;
|
||||
|
||||
//if (!options.mouseupMovements && !data.sketch.isDrawing) return;
|
||||
// This would grab all penup strokes AFTER drawing something on the canvas for the first time.
|
||||
// Grab penup strokes AFTER drawing something on the canvas for the first time.
|
||||
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();
|
||||
|
||||
var coords = data.coords[idx];
|
||||
var last = coords[coords.length - 1];
|
||||
if (last) {
|
||||
var brush = data.sketch.beginPath();
|
||||
if (data.sketch.isDrawing) {
|
||||
// Style for regular, pendown strokes.
|
||||
brush.lineStyle(options.graphics.strokeStyle, options.graphics.lineWidth);
|
||||
} else if (options.mouseupMovements.visible !== false) {
|
||||
// Style for penup strokes.
|
||||
brush.lineStyle(options.mouseupMovements.strokeStyle || '#DDD', options.mouseupMovements.lineWidth || 1);
|
||||
}
|
||||
brush.line(last[0], last[1], p.x, p.y).stroke().closePath();
|
||||
}
|
||||
|
||||
saveMousePos(idx, data, p);
|
||||
|
||||
if (typeof options.events.mousemove === 'function') {
|
||||
|
|
@ -533,12 +537,15 @@
|
|||
* @private
|
||||
*/
|
||||
function upHandler(e) {
|
||||
var idx = e.identifier || 0;
|
||||
var elem = $(e.target), data = elem.data(namespace), options = data.options;
|
||||
|
||||
var idx = e.identifier || 0,
|
||||
elem = $(e.target),
|
||||
data = elem.data(namespace),
|
||||
options = data.options;
|
||||
// Exit early if interactivity is disabled.
|
||||
if (!options.interactive) return;
|
||||
|
||||
data.sketch.isDrawing = false;
|
||||
|
||||
data.strokes.push(data.coords[idx]);
|
||||
data.coords[idx] = [];
|
||||
|
||||
|
|
@ -547,4 +554,28 @@
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function execTouchEvent(e, callback) {
|
||||
var elem = $(e.target), data = elem.data(namespace), options = data.options;
|
||||
if (options.multitouch) {
|
||||
// Track all fingers.
|
||||
var touches = e.originalEvent.changedTouches;
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
var touch = touches[i];
|
||||
// Add event type and finger ID.
|
||||
touch.type = e.type;
|
||||
touch.identifier = i;
|
||||
callback(touch);
|
||||
}
|
||||
} else {
|
||||
// Track only the current finger.
|
||||
var touch = e.originalEvent.touches[0];
|
||||
touch.type = e.type;
|
||||
touch.identifier = 0;
|
||||
callback(touch);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
/*!
|
||||
* Memento plugin for jQuery Sketchable | v2.0 | Luis A. Leiva | MIT license
|
||||
* Memento plugin for jQuery Sketchable | v2.1 | Luis A. Leiva | MIT license
|
||||
*/
|
||||
|
||||
/* eslint-env browser */
|
||||
/* global jQuery */
|
||||
;(function($) {
|
||||
|
||||
// Custom namespace ID, for private data bindind.
|
||||
|
|
@ -12,7 +13,7 @@
|
|||
* This class implements the <a href="https://en.wikipedia.org/wiki/Memento_pattern">Memento pattern</a>
|
||||
* and is part of the {@link $.fn.sketchable.plugins.memento} plugin.
|
||||
* @class
|
||||
* @version 2.0
|
||||
* @version 2.1
|
||||
* @example
|
||||
* var sketcher = $('canvas').sketchable();
|
||||
* // This is internally done by the plugin, plus some checks:
|
||||
|
|
@ -24,37 +25,12 @@
|
|||
var stpos = -1;
|
||||
var self = this;
|
||||
/**
|
||||
* Update state.
|
||||
* @param {Image} snapshot Image object.
|
||||
* @param {Array} strokes Strokes associated with snapshot.
|
||||
* @private
|
||||
*/
|
||||
function prev() {
|
||||
if (stpos > 0) {
|
||||
stpos--;
|
||||
var snapshot = new Image();
|
||||
snapshot.src = stack[stpos].image;
|
||||
snapshot.onload = function() {
|
||||
restore(this);
|
||||
};
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function next() {
|
||||
if (stpos < stack.length - 1) {
|
||||
stpos++;
|
||||
var snapshot = new Image();
|
||||
snapshot.src = stack[stpos].image;
|
||||
snapshot.onload = function() {
|
||||
restore(this);
|
||||
};
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Snashot restorer.
|
||||
* @param {String} snapshot Base64 image.
|
||||
* @private
|
||||
*/
|
||||
function restore(snapshot) {
|
||||
function draw(snapshot, strokes) {
|
||||
// Manipulate canvas via jQuery sketchable API.
|
||||
// This way, we don't lose default drawing settings et al.
|
||||
$instance.sketchable('handler', function(elem, data) {
|
||||
|
|
@ -64,9 +40,9 @@
|
|||
data.sketch.clear();
|
||||
data.sketch.graphics.drawImage(snapshot, 0,0);
|
||||
// Update strokes.
|
||||
data.strokes = stack[stpos].strokes.slice();
|
||||
data.strokes = strokes.slice();
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Key event manager.
|
||||
* - Undo: "Ctrl + Z"
|
||||
|
|
@ -89,14 +65,16 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* Goes back to the last saved state, if available.
|
||||
* @return {MementoCanvas} Class instance.
|
||||
*/
|
||||
this.undo = function() {
|
||||
prev();
|
||||
if (stpos > 0) {
|
||||
stpos--;
|
||||
this.restore();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
|
|
@ -104,7 +82,10 @@
|
|||
* @return {MementoCanvas} Class instance.
|
||||
*/
|
||||
this.redo = function() {
|
||||
next();
|
||||
if (stpos < stack.length - 1) {
|
||||
stpos++;
|
||||
this.restore();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
|
|
@ -114,7 +95,8 @@
|
|||
this.reset = function() {
|
||||
stack = [];
|
||||
stpos = -1;
|
||||
return this;
|
||||
// Save blank state afterward.
|
||||
return this.save();
|
||||
};
|
||||
/**
|
||||
* Save current state.
|
||||
|
|
@ -134,6 +116,28 @@
|
|||
});
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* Read current state: `{ image:String, strokes:Array }`.
|
||||
* @return {Object}
|
||||
*/
|
||||
this.state = function() {
|
||||
// Create a fresh copy of the current state.
|
||||
return JSON.parse(JSON.stringify(stack[stpos]));
|
||||
};
|
||||
/**
|
||||
* Restore state.
|
||||
* @param {Object} state Canvas state: `{ image:String, strokes:Array }`. Default: current state.
|
||||
* @private
|
||||
*/
|
||||
this.restore = function(state) {
|
||||
if (!state) state = stack[stpos];
|
||||
|
||||
var snapshot = new Image();
|
||||
snapshot.src = state.image;
|
||||
snapshot.onload = function() {
|
||||
draw(this, state.strokes);
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Init instance. Currently just (re)attach key event listeners.
|
||||
* @return {MementoCanvas} Class instance.
|
||||
|
|
@ -141,7 +145,8 @@
|
|||
this.init = function() {
|
||||
$(document).off('keypress', keyManager);
|
||||
$(document).on('keypress', keyManager);
|
||||
return this;
|
||||
// Save blank state to begin with.
|
||||
return this.save();
|
||||
};
|
||||
/**
|
||||
* Destroy instance: reset state and remove key event listeners.
|
||||
|
|
@ -152,11 +157,11 @@
|
|||
return this.reset();
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Memento plugin constructor for jQuery Sketchable instances.
|
||||
* @param {Object} $instance - A jQuery Sketchable instance.
|
||||
* @param {Object} $instance jQuery Sketchable instance.
|
||||
* @memberof $.fn.sketchable.plugins
|
||||
*/
|
||||
$.fn.sketchable.plugins.memento = function($instance) {
|
||||
|
|
@ -165,7 +170,7 @@
|
|||
|
||||
var callbacks = {
|
||||
clear: function(elem, data) {
|
||||
data.memento.reset().save();
|
||||
data.memento.reset();
|
||||
},
|
||||
mouseup: function(elem, data, evt) {
|
||||
data.memento.save(evt);
|
||||
|
|
@ -176,24 +181,24 @@
|
|||
};
|
||||
|
||||
// A helper function to override user-defined event listeners.
|
||||
function override(ev) {
|
||||
function override(evName) {
|
||||
// Flag event override so that it doesn't get fired more than once.
|
||||
if (config.options[ev + '$bound']) return;
|
||||
config.options[ev + '$bound'] = true;
|
||||
if (config.options['_bound$' + evName]) return;
|
||||
config.options['_bound$' + evName] = true;
|
||||
|
||||
if (config.options.events && typeof config.options.events[ev] === 'function') {
|
||||
if (config.options.events && typeof config.options.events[evName] === 'function') {
|
||||
// User has defined this event, so wrap it.
|
||||
var fn = config.options.events[ev];
|
||||
config.options.events[ev] = function() {
|
||||
var fn = config.options.events[evName];
|
||||
config.options.events[evName] = function() {
|
||||
// Exec original function first, then exec our callback.
|
||||
fn.apply($instance, arguments);
|
||||
callbacks[ev].apply($instance, arguments);
|
||||
callbacks[evName].apply($instance, arguments);
|
||||
}
|
||||
} else {
|
||||
// User has not defined this event, so attach our callback.
|
||||
config.options.events[ev] = callbacks[ev];
|
||||
config.options.events[evName] = callbacks[evName];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Note: the init event is used to create sketchable instances,
|
||||
// therefore it should NOT be overriden.
|
||||
|
|
@ -204,38 +209,67 @@
|
|||
|
||||
// Expose public API: all jQuery sketchable instances will have these methods.
|
||||
$.extend($.fn.sketchable.api, {
|
||||
/**
|
||||
* Goes back to the previous CANVAS state, if available.
|
||||
* @memberof $.fn.sketchable
|
||||
* @example jqueryElem.sketchable('undo');
|
||||
*/
|
||||
undo: function() {
|
||||
var elem = $(this), data = elem.data(namespace);
|
||||
data.memento.undo();
|
||||
},
|
||||
/**
|
||||
* Goes forward to the previous CANVAS state, if available.
|
||||
* @memberof $.fn.sketchable
|
||||
* @example jqueryElem.sketchable('redo');
|
||||
*/
|
||||
redo: function() {
|
||||
var elem = $(this), data = elem.data(namespace);
|
||||
data.memento.redo();
|
||||
},
|
||||
/**
|
||||
* Save a snapshot of the current CANVAS status.
|
||||
* @memberof $.fn.sketchable
|
||||
* @example jqueryElem.sketchable('save');
|
||||
*/
|
||||
save: function() {
|
||||
var elem = $(this), data = elem.data(namespace);
|
||||
data.memento.save();
|
||||
// Namespace methods to avoid collisions with other plugins.
|
||||
memento: {
|
||||
/**
|
||||
* Goes back to the previous CANVAS state, if available.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof $.fn.sketchable
|
||||
* @example jqueryElem.sketchable('memento.undo');
|
||||
*/
|
||||
undo: function() {
|
||||
var data = $(this).data(namespace);
|
||||
return data.memento.undo();
|
||||
},
|
||||
/**
|
||||
* Goes forward to the previous CANVAS state, if available.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof $.fn.sketchable
|
||||
* @example jqueryElem.sketchable('memento.redo');
|
||||
*/
|
||||
redo: function() {
|
||||
var data = $(this).data(namespace);
|
||||
return data.memento.redo();
|
||||
},
|
||||
/**
|
||||
* Save a snapshot of the current CANVAS status.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof $.fn.sketchable
|
||||
* @example jqueryElem.sketchable('memento.save');
|
||||
*/
|
||||
save: function() {
|
||||
var data = $(this).data(namespace);
|
||||
return data.memento.save();
|
||||
},
|
||||
/**
|
||||
* Read current snapshot of the CANVAS state: `{ image:String, strokes:Array }`.
|
||||
* @return {Object}
|
||||
* @memberof Sketchable
|
||||
* @example var state = jqueryElem.sketchable('memento.state');
|
||||
*/
|
||||
state: function() {
|
||||
var data = $(this).data(namespace);
|
||||
return data.memento.state();
|
||||
},
|
||||
/**
|
||||
* Restore a snapshot of the CANVAS.
|
||||
* @param {Object} state
|
||||
* @param {String} state.image Base64 image.
|
||||
* @param {Array} state.strokes Associated strokes.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof Sketchable
|
||||
* @example jqueryElem.sketchable('memento.restore', state);
|
||||
*/
|
||||
restore: function(state) {
|
||||
var data = $(this).data(namespace);
|
||||
return data.memento.restore(state);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize plugin here.
|
||||
config.memento = new MementoCanvas($instance);
|
||||
config.memento.init().save();
|
||||
config.memento.init();
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
|
|
|||
132
sketchable.js
132
sketchable.js
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Sketchable | v2.0 | Luis A. Leiva | MIT license
|
||||
* Sketchable | v2.1 | Luis A. Leiva | MIT license
|
||||
* A plugin for the jSketch drawing library.
|
||||
*/
|
||||
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
* @param {Object} [options] - Configuration (default: {@link Sketchable#defaults}).
|
||||
* @class
|
||||
* @global
|
||||
* @version 1.9
|
||||
* @version 2.1
|
||||
* @author Luis A. Leiva
|
||||
* @license MIT
|
||||
* @example
|
||||
|
|
@ -84,6 +84,10 @@
|
|||
timestamp: (new Date).getTime(),
|
||||
// Save a pointer to the drawing canvas (jSketch instance).
|
||||
sketch: sketch,
|
||||
// Save also a pointer to the Sketchable instance.
|
||||
// In the jQuery version this is not needed,
|
||||
// since we access the instance via `$('selector').sketchable('method')`.
|
||||
instance: this,
|
||||
// Save also a pointer to the given options.
|
||||
options: options
|
||||
};
|
||||
|
|
@ -112,7 +116,7 @@
|
|||
config: function(options) {
|
||||
var elem = this.elem, data = dataBind(elem)[namespace];
|
||||
if (options) { // setter
|
||||
data.options = deepExtend({}, Sketchable.prototype.defaults, options || {});
|
||||
data.options = deepExtend({}, Sketchable.prototype.defaults, data.options, options);
|
||||
postProcess(elem);
|
||||
return this;
|
||||
} else { // getter
|
||||
|
|
@ -253,11 +257,11 @@
|
|||
* @static
|
||||
* @example
|
||||
* // The following is the default configuration:
|
||||
* new Sketchable('canvas', {
|
||||
* new Sketchable('#canvasId', {
|
||||
* interactive: true,
|
||||
* mouseupMovements: false,
|
||||
* relTimestamps: false,
|
||||
* multitouch: false,
|
||||
* multitouch: true,
|
||||
* cssCursors: true,
|
||||
* filterCoords: false,
|
||||
* // Event hooks.
|
||||
|
|
@ -292,7 +296,7 @@
|
|||
* lineJoin: 'round',
|
||||
* miterLimit: 10
|
||||
* }
|
||||
* });
|
||||
* };
|
||||
*/
|
||||
Sketchable.prototype.defaults = {
|
||||
// In interactive mode, it's possible to draw via mouse/pen/touch input.
|
||||
|
|
@ -300,7 +304,7 @@
|
|||
// 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,
|
||||
|
|
@ -377,11 +381,7 @@
|
|||
* @private
|
||||
*/
|
||||
function saveMousePos(idx, data, pt) {
|
||||
// Ensure that coords is properly initialized.
|
||||
if (!data.coords[idx]) {
|
||||
data.coords[idx] = [];
|
||||
}
|
||||
// Use pointer for easy handling.
|
||||
// Current coords are already initialized.
|
||||
var coords = data.coords[idx];
|
||||
|
||||
var time = (new Date).getTime();
|
||||
|
|
@ -429,31 +429,6 @@
|
|||
upHandler(e);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function execTouchEvent(e, callback) {
|
||||
var elem = e.target, data = dataBind(elem)[namespace], options = data.options;
|
||||
if (options.multitouch) {
|
||||
// Track all fingers.
|
||||
var touches = e.changedTouches;
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
var touch = touches[i];
|
||||
// Add event type and finger ID.
|
||||
touch.type = e.type;
|
||||
touch.identifier = i;
|
||||
callback(touch);
|
||||
}
|
||||
} else {
|
||||
// Track only the current finger.
|
||||
var touch = e.touches[0];
|
||||
touch.type = e.type;
|
||||
touch.identifier = 0;
|
||||
callback(touch);
|
||||
}
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
|
@ -485,26 +460,29 @@
|
|||
// Don't handle right clicks.
|
||||
if (Event.isRightClick(e)) return false;
|
||||
|
||||
var idx = e.identifier || 0;
|
||||
var elem = e.target, data = dataBind(elem)[namespace], options = data.options;
|
||||
var idx = e.identifier || 0,
|
||||
elem = e.target,
|
||||
data = dataBind(elem)[namespace],
|
||||
options = data.options;
|
||||
// Exit early if interactivity is disabled.
|
||||
if (!options.interactive) return;
|
||||
|
||||
data.sketch.isDrawing = true;
|
||||
|
||||
var p = getMousePos(e);
|
||||
// Mark visually 1st point of stroke.
|
||||
if (options.graphics.firstPointSize > 0) {
|
||||
data.sketch.beginFill(options.graphics.fillStyle).fillCircle(p.x, p.y, options.graphics.firstPointSize).endFill();
|
||||
}
|
||||
|
||||
// Ensure that coords is properly initialized.
|
||||
if (!data.coords[idx]) {
|
||||
data.coords[idx] = [];
|
||||
}
|
||||
var coords = data.coords[idx];
|
||||
if (!coords) coords = [];
|
||||
// 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] = [];
|
||||
}
|
||||
if (coords.length > 0) data.strokes.push(coords);
|
||||
// In any case, ensure that coords is properly reset/initialized.
|
||||
data.coords[idx] = [];
|
||||
|
||||
saveMousePos(idx, data, p);
|
||||
|
||||
if (typeof options.events.mousedown === 'function') {
|
||||
|
|
@ -516,19 +494,31 @@
|
|||
* @private
|
||||
*/
|
||||
function moveHandler(e) {
|
||||
var idx = e.identifier || 0;
|
||||
var elem = e.target, data = dataBind(elem)[namespace], options = data.options;
|
||||
|
||||
var idx = e.identifier || 0
|
||||
elem = e.target,
|
||||
data = dataBind(elem)[namespace],
|
||||
options = data.options;
|
||||
// Exit early if interactivity is disabled.
|
||||
if (!options.interactive) return;
|
||||
//if (!options.mouseupMovements && !data.sketch.isDrawing) return;
|
||||
// This would grab all penup strokes AFTER drawing something on the canvas for the first time.
|
||||
// Grab penup strokes AFTER drawing something on the canvas for the first time.
|
||||
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();
|
||||
|
||||
var coords = data.coords[idx];
|
||||
var last = coords[coords.length - 1];
|
||||
if (last) {
|
||||
var brush = data.sketch.beginPath();
|
||||
if (data.sketch.isDrawing) {
|
||||
// Style for regular, pendown strokes.
|
||||
brush.lineStyle(options.graphics.strokeStyle, options.graphics.lineWidth);
|
||||
} else if (options.mouseupMovements.visible !== false) {
|
||||
// Style for penup strokes.
|
||||
brush.lineStyle(options.mouseupMovements.strokeStyle || '#DDD', options.mouseupMovements.lineWidth || 1);
|
||||
}
|
||||
brush.line(last[0], last[1], p.x, p.y).stroke().closePath();
|
||||
}
|
||||
|
||||
saveMousePos(idx, data, p);
|
||||
|
||||
if (typeof options.events.mousemove === 'function') {
|
||||
|
|
@ -540,12 +530,15 @@
|
|||
* @private
|
||||
*/
|
||||
function upHandler(e) {
|
||||
var idx = e.identifier || 0;
|
||||
var elem = e.target, data = dataBind(elem)[namespace], options = data.options;
|
||||
|
||||
var idx = e.identifier || 0
|
||||
elem = e.target,
|
||||
data = dataBind(elem)[namespace],
|
||||
options = data.options;
|
||||
// Exit early if interactivity is disabled.
|
||||
if (!options.interactive) return;
|
||||
|
||||
data.sketch.isDrawing = false;
|
||||
|
||||
data.strokes.push(data.coords[idx]);
|
||||
data.coords[idx] = [];
|
||||
|
||||
|
|
@ -554,6 +547,31 @@
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function execTouchEvent(e, callback) {
|
||||
var elem = e.target, data = dataBind(elem)[namespace], options = data.options;
|
||||
if (options.multitouch) {
|
||||
// Track all fingers.
|
||||
var touches = e.changedTouches;
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
var touch = touches[i];
|
||||
// Add event type and finger ID.
|
||||
touch.type = e.type;
|
||||
touch.identifier = i;
|
||||
callback(touch);
|
||||
}
|
||||
} else {
|
||||
// Track only the current finger.
|
||||
var touch = e.touches[0];
|
||||
touch.type = e.type;
|
||||
touch.identifier = 0;
|
||||
callback(touch);
|
||||
}
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
// Expose.
|
||||
window.Sketchable = Sketchable;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Memento plugin for Sketchable | v2.0 | Luis A. Leiva | MIT license
|
||||
* Memento plugin for Sketchable | v2.1 | Luis A. Leiva | MIT license
|
||||
*/
|
||||
|
||||
// XXX: Requires `sketchable.utils.js` to be loaded first.
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* This class implements the <a href="https://en.wikipedia.org/wiki/Memento_pattern">Memento pattern</a>
|
||||
* and is part of the {@link Sketchable.plugins.memento} plugin.
|
||||
* @class
|
||||
* @version 2.0
|
||||
* @version 2.1
|
||||
* @example
|
||||
* var sketcher = new Sketchable('canvas');
|
||||
* // This is internally done by the plugin, plus some checks:
|
||||
|
|
@ -27,38 +27,13 @@
|
|||
var stpos = -1;
|
||||
var self = this;
|
||||
/**
|
||||
* Update state.
|
||||
* @param {Image} snapshot Image object.
|
||||
* @param {Array} strokes Strokes associated with snapshot.
|
||||
* @private
|
||||
*/
|
||||
function prev() {
|
||||
if (stpos > 0) {
|
||||
stpos--;
|
||||
var snapshot = new Image();
|
||||
snapshot.src = stack[stpos].image;
|
||||
snapshot.onload = function() {
|
||||
restore(this);
|
||||
};
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function next() {
|
||||
if (stpos < stack.length - 1) {
|
||||
stpos++;
|
||||
var snapshot = new Image();
|
||||
snapshot.src = stack[stpos].image;
|
||||
snapshot.onload = function() {
|
||||
restore(this);
|
||||
};
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Snashot restorer.
|
||||
* @param {String} snapshot Base64 image.
|
||||
* @private
|
||||
*/
|
||||
function restore(snapshot) {
|
||||
// Manipulate canvas via jQuery sketchable API.
|
||||
function draw(snapshot, strokes) {
|
||||
// Manipulate canvas via Sketchable API.
|
||||
// This way, we don't lose default drawing settings et al.
|
||||
instance.handler(function(elem, data) {
|
||||
//data.sketch.clear().drawImage(snapshot.src);
|
||||
|
|
@ -67,9 +42,9 @@
|
|||
data.sketch.clear();
|
||||
data.sketch.graphics.drawImage(snapshot, 0,0);
|
||||
// Update strokes.
|
||||
data.strokes = stack[stpos].strokes.slice();
|
||||
data.strokes = strokes.slice();
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Key event manager.
|
||||
* - Undo: "Ctrl + Z"
|
||||
|
|
@ -92,14 +67,16 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* Goes back to the last saved state, if available.
|
||||
* @return {MementoCanvas} Class instance.
|
||||
*/
|
||||
this.undo = function() {
|
||||
prev();
|
||||
if (stpos > 0) {
|
||||
stpos--;
|
||||
this.restore();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
|
|
@ -107,7 +84,10 @@
|
|||
* @return {MementoCanvas} Class instance.
|
||||
*/
|
||||
this.redo = function() {
|
||||
next();
|
||||
if (stpos < stack.length - 1) {
|
||||
stpos++;
|
||||
this.restore();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
|
|
@ -117,7 +97,8 @@
|
|||
this.reset = function() {
|
||||
stack = [];
|
||||
stpos = -1;
|
||||
return this;
|
||||
// Save blank state afterward.
|
||||
return this.save();
|
||||
};
|
||||
/**
|
||||
* Save current state.
|
||||
|
|
@ -137,6 +118,28 @@
|
|||
});
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* Read current state: `{ image:String, strokes:Array }`.
|
||||
* @return {Object}
|
||||
*/
|
||||
this.state = function() {
|
||||
// Create a fresh copy of the current state.
|
||||
return JSON.parse(JSON.stringify(stack[stpos]));
|
||||
};
|
||||
/**
|
||||
* Restore state.
|
||||
* @param {Object} state Canvas state: `{ image:String, strokes:Array }`. Default: current state.
|
||||
* @private
|
||||
*/
|
||||
this.restore = function(state) {
|
||||
if (!state) state = stack[stpos];
|
||||
|
||||
var snapshot = new Image();
|
||||
snapshot.src = state.image;
|
||||
snapshot.onload = function() {
|
||||
draw(this, state.strokes);
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Init instance. Currently just (re)attach key event listeners.
|
||||
* @return {MementoCanvas} Class instance.
|
||||
|
|
@ -144,7 +147,8 @@
|
|||
this.init = function() {
|
||||
Event.remove(document, 'keypress', keyManager);
|
||||
Event.add(document, 'keypress', keyManager);
|
||||
return this;
|
||||
// Save blank state to begin with.
|
||||
return this.save();
|
||||
};
|
||||
/**
|
||||
* Destroy instance: reset state and remove key event listeners.
|
||||
|
|
@ -155,11 +159,11 @@
|
|||
return this.reset();
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Memento plugin constructor for jQuery Sketchable instances.
|
||||
* @param {Object} sketchable - An Sketchable instance.
|
||||
* Memento plugin constructor for Sketchable instances.
|
||||
* @param {Object} sketchable Sketchable instance.
|
||||
* @memberof Sketchable#plugins
|
||||
*/
|
||||
Sketchable.prototype.plugins.memento = function(instance) {
|
||||
|
|
@ -168,7 +172,7 @@
|
|||
|
||||
var callbacks = {
|
||||
clear: function(elem, data) {
|
||||
data.memento.reset().save();
|
||||
data.memento.reset();
|
||||
},
|
||||
mouseup: function(elem, data, evt) {
|
||||
data.memento.save(evt);
|
||||
|
|
@ -179,24 +183,24 @@
|
|||
};
|
||||
|
||||
// A helper function to override user-defined event listeners.
|
||||
function override(ev) {
|
||||
function override(evName) {
|
||||
// Flag event override so that it doesn't get fired more than once.
|
||||
if (config.options[ev + '$bound']) return;
|
||||
config.options[ev + '$bound'] = true;
|
||||
if (config.options['_bound$' + evName]) return;
|
||||
config.options['_bound$' + evName] = true;
|
||||
|
||||
if (config.options.events && typeof config.options.events[ev] === 'function') {
|
||||
if (config.options.events && typeof config.options.events[evName] === 'function') {
|
||||
// User has defined this event, so wrap it.
|
||||
var fn = config.options.events[ev];
|
||||
config.options.events[ev] = function() {
|
||||
var fn = config.options.events[evName];
|
||||
config.options.events[evName] = function() {
|
||||
// Exec original function first, then exec our callback.
|
||||
fn.apply(instance, arguments);
|
||||
callbacks[ev].apply(instance, arguments);
|
||||
callbacks[evName].apply(instance, arguments);
|
||||
}
|
||||
} else {
|
||||
// User has not defined this event, so attach our callback.
|
||||
config.options.events[ev] = callbacks[ev];
|
||||
config.options.events[evName] = callbacks[evName];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Note: the init event is used to create Sketchable instances,
|
||||
// therefore it should NOT be overriden.
|
||||
|
|
@ -206,39 +210,68 @@
|
|||
}
|
||||
|
||||
// Expose public API: all Sketchable instances will have these methods.
|
||||
deepExtend(Sketchable.prototype, {
|
||||
/**
|
||||
* Goes back to the previous CANVAS state, if available.
|
||||
* @memberof Sketchable
|
||||
* @example sketchableInstance.undo();
|
||||
*/
|
||||
undo: function() {
|
||||
var elem = this.elem, data = dataBind(elem)[namespace];
|
||||
data.memento.undo();
|
||||
},
|
||||
/**
|
||||
* Goes forward to the previous CANVAS state, if available.
|
||||
* @memberof Sketchable
|
||||
* @example sketchableInstance.redo();
|
||||
*/
|
||||
redo: function() {
|
||||
var elem = this.elem, data = dataBind(elem)[namespace];
|
||||
data.memento.redo();
|
||||
},
|
||||
/**
|
||||
* Save a snapshot of the current CANVAS status.
|
||||
* @memberof Sketchable
|
||||
* @example sketchableInstance.save();
|
||||
*/
|
||||
save: function() {
|
||||
var elem = this.elem, data = dataBind(elem)[namespace];
|
||||
data.memento.save();
|
||||
deepExtend(instance, {
|
||||
// Namespace methods to avoid collisions with other plugins.
|
||||
memento: {
|
||||
/**
|
||||
* Goes back to the previous CANVAS state, if available.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof Sketchable
|
||||
* @example sketchableInstance.memento.undo();
|
||||
*/
|
||||
undo: function() {
|
||||
var data = dataBind(instance.elem)[namespace];
|
||||
return data.memento.undo();
|
||||
},
|
||||
/**
|
||||
* Goes forward to the previous CANVAS state, if available.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof Sketchable
|
||||
* @example sketchableInstance.memento.redo();
|
||||
*/
|
||||
redo: function() {
|
||||
var data = dataBind(instance.elem)[namespace];
|
||||
return data.memento.redo();
|
||||
},
|
||||
/**
|
||||
* Save a snapshot of the current CANVAS state.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof Sketchable
|
||||
* @example sketchableInstance.memento.save();
|
||||
*/
|
||||
save: function() {
|
||||
var data = dataBind(instance.elem)[namespace];
|
||||
return data.memento.save();
|
||||
},
|
||||
/**
|
||||
* Read current snapshot of the CANVAS state: `{ image:String, strokes:Array }`.
|
||||
* @return {Object}
|
||||
* @memberof Sketchable
|
||||
* @example var state = sketchableInstance.memento.state();
|
||||
*/
|
||||
state: function() {
|
||||
var data = dataBind(instance.elem)[namespace];
|
||||
return data.memento.state();
|
||||
},
|
||||
/**
|
||||
* Restore a snapshot of the CANVAS.
|
||||
* @param {Object} state
|
||||
* @param {String} state.image Base64 image.
|
||||
* @param {Array} state.strokes Associated strokes.
|
||||
* @return {MementoCanvas}
|
||||
* @memberof Sketchable
|
||||
* @example sketchableInstance.memento.restore();
|
||||
*/
|
||||
restore: function(state) {
|
||||
var data = dataBind(instance.elem)[namespace];
|
||||
return data.memento.restore(state);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize plugin here.
|
||||
config.memento = new MementoCanvas(instance);
|
||||
config.memento.init().save();
|
||||
config.memento.init();
|
||||
};
|
||||
|
||||
})(this);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
(function(){
|
||||
var cache = [0], expando = 'data' + +(new Date);
|
||||
(function() {
|
||||
var cache = [0], expando = 'data' + Date.now();
|
||||
function data(elem) {
|
||||
var cacheIndex = elem[expando],
|
||||
nextCacheIndex = cache.length;
|
||||
|
|
@ -17,9 +17,11 @@
|
|||
* @example
|
||||
* var elem = document.getElementById('foo');
|
||||
* // Attach private data to element:
|
||||
* dataBind(elem)['some-name'] = { value: 42 };
|
||||
* dataBind(elem).someName = { value: 42 };
|
||||
* dataBind(elem)['other-name'] = { value: 43 };
|
||||
* // Read private data from element:
|
||||
* var dat = dataBind(elem)['some-name'];
|
||||
* var some = dataBind(elem).someName;
|
||||
* var other = dataBind(elem)['other-name'];
|
||||
*/
|
||||
window.dataBind = data;
|
||||
})();
|
||||
|
|
|
|||
Loading…
Reference in New Issue