diff --git a/README.md b/README.md index 1310515..6760929 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ When instantiating the drawingboard, you can pass a few options as the 2nd param * `enlargeYourContainer`: how should be sized the drawingboard? When `true`, the CSS width and height will be set on the final board's *canvas*, ie the drawing zone. In the example above, that means the board's container will be taller than 400px because of the controls height. If `false`, the CSS width and height will be set on the board's container. That means the addition of the canvas and the controls will be 400px high. `false` by default. * `errorMessage`: html string to put in the board's element on browsers that don't support canvas. * `stretchImg`: default behavior of image setting on the canvas: set to the canvas width/height or not? `false` by default +* `keepImgRatio` : when stretch image, do we keep image ratio? `true` by default. ## Controls diff --git a/dist/drawingboard.css b/dist/drawingboard.css index 90920c6..373091d 100644 --- a/dist/drawingboard.css +++ b/dist/drawingboard.css @@ -1,5 +1,5 @@ /* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js -* Copyright (c) 2015 Emmanuel Pelletier +* Copyright (c) 2017 Emmanuel Pelletier * Licensed MIT */ .drawing-board, .drawing-board * { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } diff --git a/dist/drawingboard.js b/dist/drawingboard.js index fbaee53..ca48942 100644 --- a/dist/drawingboard.js +++ b/dist/drawingboard.js @@ -1,5 +1,5 @@ /* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js -* Copyright (c) 2015 Emmanuel Pelletier +* Copyright (c) 2017 Emmanuel Pelletier * Licensed MIT */ (function() { @@ -369,7 +369,8 @@ DrawingBoard.Board.defaultOpts = { droppable: false, enlargeYourContainer: false, errorMessage: "

It seems you use an obsolete browser. Update it to start drawing.

", - stretchImg: false //when setting the canvas img, strech the image at the whole canvas size when this opt is true + stretchImg: false, //when setting the canvas img, strech the image at the whole canvas size when this opt is true + keepImgRatio: true, // when stretch the image to the canvas size, keep image ratio when this opt is true }; @@ -592,6 +593,7 @@ DrawingBoard.Board.prototype = { setImg: function(src, opts) { opts = $.extend({ stretch: this.opts.stretchImg, + keepRatio: this.opts.keepImgRatio, callback: null }, opts); @@ -603,7 +605,18 @@ DrawingBoard.Board.prototype = { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); if (opts.stretch) { - ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); + if(opts.keepRatio) { + var canvasRatio = ctx.canvas.width / ctx.canvas.height; // measure of wide + var imgRatio = img.width / img.height; + var rWidth = ctx.canvas.width * (imgRatio / canvasRatio); + var rHeight = ctx.canvas.height * (imgRatio * canvasRatio); + if(canvasRatio > imgRatio) // canvas is more wide, keep height + ctx.drawImage(img, (ctx.canvas.width - rWidth) / 2, 0, rWidth, ctx.canvas.height); + else // canvas is more narrow, keep width + ctx.drawImage(img, 0, (ctx.canvas.height - rHeight) / 2, ctx.canvas.width, rHeight); + } else { + ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); + } } else { ctx.drawImage(img, 0, 0); } diff --git a/dist/drawingboard.nocontrol.css b/dist/drawingboard.nocontrol.css index ddb4dc8..6ccfe4a 100644 --- a/dist/drawingboard.nocontrol.css +++ b/dist/drawingboard.nocontrol.css @@ -1,5 +1,5 @@ /* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js -* Copyright (c) 2015 Emmanuel Pelletier +* Copyright (c) 2017 Emmanuel Pelletier * Licensed MIT */ .drawing-board, .drawing-board * { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } diff --git a/dist/drawingboard.nocontrol.js b/dist/drawingboard.nocontrol.js index cd91069..56b3e95 100644 --- a/dist/drawingboard.nocontrol.js +++ b/dist/drawingboard.nocontrol.js @@ -1,5 +1,5 @@ /* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js -* Copyright (c) 2015 Emmanuel Pelletier +* Copyright (c) 2017 Emmanuel Pelletier * Licensed MIT */ (function() { @@ -369,7 +369,8 @@ DrawingBoard.Board.defaultOpts = { droppable: false, enlargeYourContainer: false, errorMessage: "

It seems you use an obsolete browser. Update it to start drawing.

", - stretchImg: false //when setting the canvas img, strech the image at the whole canvas size when this opt is true + stretchImg: false, //when setting the canvas img, strech the image at the whole canvas size when this opt is true + keepImgRatio: true, // when stretch the image to the canvas size, keep image ratio when this opt is true }; @@ -592,6 +593,7 @@ DrawingBoard.Board.prototype = { setImg: function(src, opts) { opts = $.extend({ stretch: this.opts.stretchImg, + keepRatio: this.opts.keepImgRatio, callback: null }, opts); @@ -603,7 +605,18 @@ DrawingBoard.Board.prototype = { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); if (opts.stretch) { - ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); + if(opts.keepRatio) { + var canvasRatio = ctx.canvas.width / ctx.canvas.height; // measure of wide + var imgRatio = img.width / img.height; + var rWidth = ctx.canvas.width * (imgRatio / canvasRatio); + var rHeight = ctx.canvas.height * (imgRatio * canvasRatio); + if(canvasRatio > imgRatio) // canvas is more wide, keep height + ctx.drawImage(img, (ctx.canvas.width - rWidth) / 2, 0, rWidth, ctx.canvas.height); + else // canvas is more narrow, keep width + ctx.drawImage(img, 0, (ctx.canvas.height - rHeight) / 2, ctx.canvas.width, rHeight); + } else { + ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); + } } else { ctx.drawImage(img, 0, 0); } diff --git a/dist/drawingboard.nocontrol.min.js b/dist/drawingboard.nocontrol.min.js index 874de44..a7928e1 100644 --- a/dist/drawingboard.nocontrol.min.js +++ b/dist/drawingboard.nocontrol.min.js @@ -1,4 +1,4 @@ /* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js -* Copyright (c) 2015 Emmanuel Pelletier +* Copyright (c) 2017 Emmanuel Pelletier * Licensed MIT */ -!function(){"use strict";function a(a,b){for(;a.length>b;)a.shift()}var b=function(a){var b=a?a:{},c={provider:function(){throw new Error("No provider!")},maxLength:30,onUpdate:function(){}};this.provider="undefined"!=typeof b.provider?b.provider:c.provider,this.maxLength="undefined"!=typeof b.maxLength?b.maxLength:c.maxLength,this.onUpdate="undefined"!=typeof b.onUpdate?b.onUpdate:c.onUpdate,this.initialItem=null,this.clear()};b.prototype.initialize=function(a){this.stack[0]=a,this.initialItem=a},b.prototype.clear=function(){this.stack=[this.initialItem],this.position=0,this.onUpdate()},b.prototype.save=function(){this.provider(function(b){a(this.stack,this.maxLength),this.position=Math.min(this.position,this.stack.length-1),this.stack=this.stack.slice(0,this.position+1),this.stack.push(b),this.position++,this.onUpdate()}.bind(this))},b.prototype.undo=function(a){if(this.canUndo()){var b=this.stack[--this.position];this.onUpdate(),a&&a(b)}},b.prototype.redo=function(a){if(this.canRedo()){var b=this.stack[++this.position];this.onUpdate(),a&&a(b)}},b.prototype.canUndo=function(){return this.position>0},b.prototype.canRedo=function(){return this.positionh;h++){if(g=g[e[h]],g===a)throw"tim: '"+e[h]+"' not found in "+b;if(h===f-1)return g}})}}(),DrawingBoard.Utils.MicroEvent=function(){},DrawingBoard.Utils.MicroEvent.prototype={bind:function(a,b){this._events=this._events||{},this._events[a]=this._events[a]||[],this._events[a].push(b)},unbind:function(a,b){this._events=this._events||{},a in this._events!=!1&&this._events[a].splice(this._events[a].indexOf(b),1)},trigger:function(a){if(this._events=this._events||{},a in this._events!=!1)for(var b=0;b=0;g--)f+=parseInt(a.css(e[g]).replace("px",""),10);return f},DrawingBoard.Utils.boxBorderWidth=function(a,b,c){return DrawingBoard.Utils._boxBorderSize(a,b,c,"width")},DrawingBoard.Utils.boxBorderHeight=function(a,b,c){return DrawingBoard.Utils._boxBorderSize(a,b,c,"height")},DrawingBoard.Utils.isColor=function(a){return a&&a.length?/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a)||-1!==$.inArray(a.substring(0,3),["rgb","hsl"]):!1},DrawingBoard.Utils.RGBToInt=function(a,b,c){var d=0;return d|=(255&a)<<16,d|=(255&b)<<8,d|=255&c},DrawingBoard.Utils.pixelAt=function(a,b,c){var d=4*(c*a.width+b),e=DrawingBoard.Utils.RGBToInt(a.data[d],a.data[d+1],a.data[d+2]);return[d,b,c,e]},DrawingBoard.Utils.compareColors=function(a,b,c){if(0===c)return a===b;var d=a>>16&255,e=b>>16&255,f=a>>8&255,g=b>>8&255,h=255&a,i=255&b;return Math.abs(d-e)<=c&&Math.abs(f-g)<=c&&Math.abs(h-i)<=c},function(){for(var a=["ms","moz","webkit","o"],b=0;b-1?c+='
':c='
'+c,this.$el.addClass("drawing-board").append(c),this.dom={$canvasWrapper:this.$el.find(".drawing-board-canvas-wrapper"),$canvas:this.$el.find(".drawing-board-canvas"),$cursor:this.$el.find(".drawing-board-cursor"),$controls:this.$el.find(".drawing-board-controls")},$.each(["left","right","center"],$.proxy(function(a,b){return this.opts.controlsPosition.indexOf(b)>-1?(this.dom.$controls.attr("data-align",b),!1):void 0},this)),this.canvas=this.dom.$canvas.get(0),this.ctx=this.canvas&&this.canvas.getContext&&this.canvas.getContext("2d")?this.canvas.getContext("2d"):null,this.color=this.opts.color,this.ctx?(this.storage=this._getStorage(),this.initHistory(),this.reset({webStorage:!1,history:!1,background:!1}),this.initControls(),this.resize(),this.reset({webStorage:!1,history:!1,background:!0}),this.restoreWebStorage(),this.initDropEvents(),void this.initDrawEvents()):(this.opts.errorMessage&&this.$el.html(this.opts.errorMessage),!1)},DrawingBoard.Board.defaultOpts={controls:["Color","DrawingMode","Size","Navigation"],controlsPosition:"top left",color:"#000000",size:1,background:"#fff",eraserColor:"background",fillTolerance:100,fillHack:!0,webStorage:"session",droppable:!1,enlargeYourContainer:!1,errorMessage:'

It seems you use an obsolete browser. Update it to start drawing.

',stretchImg:!1},DrawingBoard.Board.prototype={mergeOptions:function(a){return a=$.extend({},DrawingBoard.Board.defaultOpts,a),a.background||"background"!==a.eraserColor||(a.eraserColor="transparent"),a},reset:function(a){a=$.extend({color:this.opts.color,size:this.opts.size,webStorage:!0,history:!0,background:!1},a),this.setMode("pencil"),a.background&&this.resetBackground(this.opts.background,$.proxy(function(){a.history&&this.saveHistory()},this)),a.color&&this.setColor(a.color),a.size&&(this.ctx.lineWidth=a.size),this.ctx.lineCap="round",this.ctx.lineJoin="round",a.webStorage&&this.saveWebStorage(),a.history&&!a.background&&this.saveHistory(),this.blankCanvas=this.getImg(),this.ev.trigger("board:reset",a)},resetBackground:function(a,b){a=a||this.opts.background;var c=DrawingBoard.Utils.isColor(a),d=this.getMode();this.setMode("pencil"),this.ctx.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),c?(this.ctx.fillStyle=a,this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),this.history.initialize(this.getImg()),b&&b()):a&&this.setImg(a,{callback:$.proxy(function(){this.history.initialize(this.getImg()),b&&b()},this)}),this.setMode(d)},resize:function(){this.dom.$controls.toggleClass("drawing-board-controls-hidden",!this.controls||!this.controls.length);var a,b,c=[this.$el.width(),DrawingBoard.Utils.boxBorderWidth(this.$el),DrawingBoard.Utils.boxBorderWidth(this.dom.$canvasWrapper,!0,!0)],d=[this.$el.height(),DrawingBoard.Utils.boxBorderHeight(this.$el),this.dom.$controls.height(),DrawingBoard.Utils.boxBorderHeight(this.dom.$controls,!1,!0),DrawingBoard.Utils.boxBorderHeight(this.dom.$canvasWrapper,!0,!0)],e=function(a,b){b=b||1;for(var c=a[0],d=1;d0&&q.push(DrawingBoard.Utils.pixelAt(c,p[e]-1,p[f])),p[e]0&&q.push(DrawingBoard.Utils.pixelAt(c,p[e],p[f]-1)),p[f]10&&this.isMouseHovering){this.dom.$cursor.css({width:this.ctx.lineWidth+"px",height:this.ctx.lineWidth+"px"});var a=DrawingBoard.Utils.tpl("translateX({{x}}px) translateY({{y}}px)",{x:this.coords.current.x-this.ctx.lineWidth/2,y:this.coords.current.y-this.ctx.lineWidth/2});this.dom.$cursor.css({transform:a,"-webkit-transform":a,"-ms-transform":a}),this.dom.$cursor.removeClass("drawing-board-utils-hidden")}else this.dom.$cursor.addClass("drawing-board-utils-hidden");if(this.isDrawing){var b=this._getMidInputCoords(this.coords.current);this.ctx.beginPath(),this.ctx.moveTo(b.x,b.y),this.ctx.quadraticCurveTo(this.coords.old.x,this.coords.old.y,this.coords.oldMid.x,this.coords.oldMid.y),this.ctx.stroke(),this.coords.old=this.coords.current,this.coords.oldMid=b}window.requestAnimationFrame&&requestAnimationFrame($.proxy(function(){this.draw()},this))},_onInputStart:function(a,b){this.coords.current=this.coords.old=b,this.coords.oldMid=this._getMidInputCoords(b),this.isDrawing=!0,window.requestAnimationFrame||this.draw(),this.ev.trigger("board:startDrawing",{e:a,coords:b}),a.stopPropagation(),a.preventDefault()},_onInputMove:function(a,b){this.coords.current=b,this.ev.trigger("board:drawing",{e:a,coords:b}),window.requestAnimationFrame||this.draw(),a.stopPropagation(),a.preventDefault()},_onInputStop:function(a,b){!this.isDrawing||a.touches&&0!==a.touches.length||(this.isDrawing=!1,this.saveWebStorage(),this.saveHistory(),this.ev.trigger("board:stopDrawing",{e:a,coords:b}),this.ev.trigger("board:userAction"),a.stopPropagation(),a.preventDefault())},_onMouseOver:function(a,b){this.isMouseHovering=!0,this.coords.old=this._getInputCoords(a),this.coords.oldMid=this._getMidInputCoords(this.coords.old),this.ev.trigger("board:mouseOver",{e:a,coords:b})},_onMouseOut:function(a,b){this.isMouseHovering=!1,this.ev.trigger("board:mouseOut",{e:a,coords:b})},_getInputCoords:function(a){a=a.originalEvent?a.originalEvent:a;var b,c,d=this.canvas.getBoundingClientRect(),e=this.dom.$canvas.width(),f=this.dom.$canvas.height();return a.touches&&1==a.touches.length?(b=a.touches[0].pageX,c=a.touches[0].pageY):(b=a.pageX,c=a.pageY),b-=this.dom.$canvas.offset().left,c-=this.dom.$canvas.offset().top,b*=e/d.width,c*=f/d.height,{x:b,y:c}},_getMidInputCoords:function(a){return{x:this.coords.old.x+a.x>>1,y:this.coords.old.y+a.y>>1}}}; \ No newline at end of file +!function(){"use strict";function a(a,b){for(;a.length>b;)a.shift()}var b=function(a){var b=a?a:{},c={provider:function(){throw new Error("No provider!")},maxLength:30,onUpdate:function(){}};this.provider="undefined"!=typeof b.provider?b.provider:c.provider,this.maxLength="undefined"!=typeof b.maxLength?b.maxLength:c.maxLength,this.onUpdate="undefined"!=typeof b.onUpdate?b.onUpdate:c.onUpdate,this.initialItem=null,this.clear()};b.prototype.initialize=function(a){this.stack[0]=a,this.initialItem=a},b.prototype.clear=function(){this.stack=[this.initialItem],this.position=0,this.onUpdate()},b.prototype.save=function(){this.provider(function(b){a(this.stack,this.maxLength),this.position=Math.min(this.position,this.stack.length-1),this.stack=this.stack.slice(0,this.position+1),this.stack.push(b),this.position++,this.onUpdate()}.bind(this))},b.prototype.undo=function(a){if(this.canUndo()){var b=this.stack[--this.position];this.onUpdate(),a&&a(b)}},b.prototype.redo=function(a){if(this.canRedo()){var b=this.stack[++this.position];this.onUpdate(),a&&a(b)}},b.prototype.canUndo=function(){return this.position>0},b.prototype.canRedo=function(){return this.positionh;h++){if(g=g[e[h]],g===a)throw"tim: '"+e[h]+"' not found in "+b;if(h===f-1)return g}})}}(),DrawingBoard.Utils.MicroEvent=function(){},DrawingBoard.Utils.MicroEvent.prototype={bind:function(a,b){this._events=this._events||{},this._events[a]=this._events[a]||[],this._events[a].push(b)},unbind:function(a,b){this._events=this._events||{},a in this._events!=!1&&this._events[a].splice(this._events[a].indexOf(b),1)},trigger:function(a){if(this._events=this._events||{},a in this._events!=!1)for(var b=0;b=0;g--)f+=parseInt(a.css(e[g]).replace("px",""),10);return f},DrawingBoard.Utils.boxBorderWidth=function(a,b,c){return DrawingBoard.Utils._boxBorderSize(a,b,c,"width")},DrawingBoard.Utils.boxBorderHeight=function(a,b,c){return DrawingBoard.Utils._boxBorderSize(a,b,c,"height")},DrawingBoard.Utils.isColor=function(a){return a&&a.length?/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a)||-1!==$.inArray(a.substring(0,3),["rgb","hsl"]):!1},DrawingBoard.Utils.RGBToInt=function(a,b,c){var d=0;return d|=(255&a)<<16,d|=(255&b)<<8,d|=255&c},DrawingBoard.Utils.pixelAt=function(a,b,c){var d=4*(c*a.width+b),e=DrawingBoard.Utils.RGBToInt(a.data[d],a.data[d+1],a.data[d+2]);return[d,b,c,e]},DrawingBoard.Utils.compareColors=function(a,b,c){if(0===c)return a===b;var d=a>>16&255,e=b>>16&255,f=a>>8&255,g=b>>8&255,h=255&a,i=255&b;return Math.abs(d-e)<=c&&Math.abs(f-g)<=c&&Math.abs(h-i)<=c},function(){for(var a=["ms","moz","webkit","o"],b=0;b-1?c+='
':c='
'+c,this.$el.addClass("drawing-board").append(c),this.dom={$canvasWrapper:this.$el.find(".drawing-board-canvas-wrapper"),$canvas:this.$el.find(".drawing-board-canvas"),$cursor:this.$el.find(".drawing-board-cursor"),$controls:this.$el.find(".drawing-board-controls")},$.each(["left","right","center"],$.proxy(function(a,b){return this.opts.controlsPosition.indexOf(b)>-1?(this.dom.$controls.attr("data-align",b),!1):void 0},this)),this.canvas=this.dom.$canvas.get(0),this.ctx=this.canvas&&this.canvas.getContext&&this.canvas.getContext("2d")?this.canvas.getContext("2d"):null,this.color=this.opts.color,this.ctx?(this.storage=this._getStorage(),this.initHistory(),this.reset({webStorage:!1,history:!1,background:!1}),this.initControls(),this.resize(),this.reset({webStorage:!1,history:!1,background:!0}),this.restoreWebStorage(),this.initDropEvents(),void this.initDrawEvents()):(this.opts.errorMessage&&this.$el.html(this.opts.errorMessage),!1)},DrawingBoard.Board.defaultOpts={controls:["Color","DrawingMode","Size","Navigation"],controlsPosition:"top left",color:"#000000",size:1,background:"#fff",eraserColor:"background",fillTolerance:100,fillHack:!0,webStorage:"session",droppable:!1,enlargeYourContainer:!1,errorMessage:'

It seems you use an obsolete browser. Update it to start drawing.

',stretchImg:!1,keepImgRatio:!0},DrawingBoard.Board.prototype={mergeOptions:function(a){return a=$.extend({},DrawingBoard.Board.defaultOpts,a),a.background||"background"!==a.eraserColor||(a.eraserColor="transparent"),a},reset:function(a){a=$.extend({color:this.opts.color,size:this.opts.size,webStorage:!0,history:!0,background:!1},a),this.setMode("pencil"),a.background&&this.resetBackground(this.opts.background,$.proxy(function(){a.history&&this.saveHistory()},this)),a.color&&this.setColor(a.color),a.size&&(this.ctx.lineWidth=a.size),this.ctx.lineCap="round",this.ctx.lineJoin="round",a.webStorage&&this.saveWebStorage(),a.history&&!a.background&&this.saveHistory(),this.blankCanvas=this.getImg(),this.ev.trigger("board:reset",a)},resetBackground:function(a,b){a=a||this.opts.background;var c=DrawingBoard.Utils.isColor(a),d=this.getMode();this.setMode("pencil"),this.ctx.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),c?(this.ctx.fillStyle=a,this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),this.history.initialize(this.getImg()),b&&b()):a&&this.setImg(a,{callback:$.proxy(function(){this.history.initialize(this.getImg()),b&&b()},this)}),this.setMode(d)},resize:function(){this.dom.$controls.toggleClass("drawing-board-controls-hidden",!this.controls||!this.controls.length);var a,b,c=[this.$el.width(),DrawingBoard.Utils.boxBorderWidth(this.$el),DrawingBoard.Utils.boxBorderWidth(this.dom.$canvasWrapper,!0,!0)],d=[this.$el.height(),DrawingBoard.Utils.boxBorderHeight(this.$el),this.dom.$controls.height(),DrawingBoard.Utils.boxBorderHeight(this.dom.$controls,!1,!0),DrawingBoard.Utils.boxBorderHeight(this.dom.$canvasWrapper,!0,!0)],e=function(a,b){b=b||1;for(var c=a[0],d=1;df?c.drawImage(d,(c.canvas.width-g)/2,0,g,c.canvas.height):c.drawImage(d,0,(c.canvas.height-h)/2,c.canvas.width,h)}else c.drawImage(d,0,0,c.canvas.width,c.canvas.height);else c.drawImage(d,0,0);c.globalCompositeOperation=e,b.callback&&b.callback()},d.src=a},getImg:function(){return this.canvas.toDataURL("image/png")},downloadImg:function(){var a=this.getImg();a=a.replace("image/png","image/octet-stream"),window.location.href=a},saveWebStorage:function(){window[this.storage]&&(window[this.storage].setItem("drawing-board-"+this.id,this.getImg()),this.ev.trigger("board:save"+this.storage.charAt(0).toUpperCase()+this.storage.slice(1),this.getImg()))},restoreWebStorage:function(){window[this.storage]&&null!==window[this.storage].getItem("drawing-board-"+this.id)&&(this.setImg(window[this.storage].getItem("drawing-board-"+this.id)),this.ev.trigger("board:restore"+this.storage.charAt(0).toUpperCase()+this.storage.slice(1),window[this.storage].getItem("drawing-board-"+this.id)))},clearWebStorage:function(){window[this.storage]&&null!==window[this.storage].getItem("drawing-board-"+this.id)&&(window[this.storage].removeItem("drawing-board-"+this.id),this.ev.trigger("board:clear"+this.storage.charAt(0).toUpperCase()+this.storage.slice(1)))},_getStorage:function(){return!this.opts.webStorage||"session"!==this.opts.webStorage&&"local"!==this.opts.webStorage?!1:this.opts.webStorage+"Storage"},initDropEvents:function(){return this.opts.droppable?(this.dom.$canvas.on("dragover dragenter drop",function(a){a.stopPropagation(),a.preventDefault()}),void this.dom.$canvas.on("drop",$.proxy(this._onCanvasDrop,this))):!1},_onCanvasDrop:function(a){a=a.originalEvent?a.originalEvent:a;var b=a.dataTransfer.files;if(!b||!b.length||-1==b[0].type.indexOf("image")||!window.FileReader)return!1;var c=new FileReader;c.readAsDataURL(b[0]),c.onload=$.proxy(function(a){this.setImg(a.target.result,{callback:$.proxy(function(){this.saveHistory()},this)}),this.ev.trigger("board:imageDropped",a.target.result),this.ev.trigger("board:userAction")},this)},setMode:function(a,b){b=b||!1,a=a||"pencil",this.ev.unbind("board:startDrawing",$.proxy(this.fill,this)),"transparent"===this.opts.eraserColor?this.ctx.globalCompositeOperation="eraser"===a?"destination-out":"source-over":("eraser"===a?"background"===this.opts.eraserColor&&DrawingBoard.Utils.isColor(this.opts.background)?this.ctx.strokeStyle=this.opts.background:DrawingBoard.Utils.isColor(this.opts.eraserColor)&&(this.ctx.strokeStyle=this.opts.eraserColor):this.mode&&"eraser"!==this.mode||(this.ctx.strokeStyle=this.color),"filler"===a&&this.ev.bind("board:startDrawing",$.proxy(this.fill,this))),this.mode=a,b||this.ev.trigger("board:mode",this.mode)},getMode:function(){return this.mode||"pencil"},setColor:function(a){var b=this;if(a=a||this.color,!DrawingBoard.Utils.isColor(a))return!1;if(this.color=a,"transparent"!==this.opts.eraserColor&&"eraser"===this.mode){var c=function(a){"eraser"!==a&&(b.strokeStyle=b.color),b.ev.unbind("board:mode",c)};this.ev.bind("board:mode",c)}else this.ctx.strokeStyle=this.color},fill:function(a){function b(a){c.data[a[d]]=i,c.data[a[d]+1]=j,c.data[a[d]+2]=k}if(this.getImg()===this.blankCanvas)return this.ctx.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),this.ctx.fillStyle=this.color,void this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);var c=this.ctx.getImageData(0,0,this.canvas.width,this.canvas.height),d=0,e=1,f=2,g=3,h=this.ctx.strokeStyle,i=parseInt(h.substr(1,2),16),j=parseInt(h.substr(3,2),16),k=parseInt(h.substr(5,2),16),l=DrawingBoard.Utils.pixelAt(c,parseInt(a.coords.x,10),parseInt(a.coords.y,10)),m=l[g],n=this.opts.fillTolerance,o=this.opts.fillHack;if(!DrawingBoard.Utils.compareColors(m,DrawingBoard.Utils.RGBToInt(i,j,k),n)){for(var p,q=[l],r=c.width-1,s=c.height-1;p=q.pop();)o&&b(p),DrawingBoard.Utils.compareColors(p[g],m,n)&&(o||b(p),p[e]>0&&q.push(DrawingBoard.Utils.pixelAt(c,p[e]-1,p[f])),p[e]0&&q.push(DrawingBoard.Utils.pixelAt(c,p[e],p[f]-1)),p[f]10&&this.isMouseHovering){this.dom.$cursor.css({width:this.ctx.lineWidth+"px",height:this.ctx.lineWidth+"px"});var a=DrawingBoard.Utils.tpl("translateX({{x}}px) translateY({{y}}px)",{x:this.coords.current.x-this.ctx.lineWidth/2,y:this.coords.current.y-this.ctx.lineWidth/2});this.dom.$cursor.css({transform:a,"-webkit-transform":a,"-ms-transform":a}),this.dom.$cursor.removeClass("drawing-board-utils-hidden")}else this.dom.$cursor.addClass("drawing-board-utils-hidden");if(this.isDrawing){var b=this._getMidInputCoords(this.coords.current);this.ctx.beginPath(),this.ctx.moveTo(b.x,b.y),this.ctx.quadraticCurveTo(this.coords.old.x,this.coords.old.y,this.coords.oldMid.x,this.coords.oldMid.y),this.ctx.stroke(),this.coords.old=this.coords.current,this.coords.oldMid=b}window.requestAnimationFrame&&requestAnimationFrame($.proxy(function(){this.draw()},this))},_onInputStart:function(a,b){this.coords.current=this.coords.old=b,this.coords.oldMid=this._getMidInputCoords(b),this.isDrawing=!0,window.requestAnimationFrame||this.draw(),this.ev.trigger("board:startDrawing",{e:a,coords:b}),a.stopPropagation(),a.preventDefault()},_onInputMove:function(a,b){this.coords.current=b,this.ev.trigger("board:drawing",{e:a,coords:b}),window.requestAnimationFrame||this.draw(),a.stopPropagation(),a.preventDefault()},_onInputStop:function(a,b){!this.isDrawing||a.touches&&0!==a.touches.length||(this.isDrawing=!1,this.saveWebStorage(),this.saveHistory(),this.ev.trigger("board:stopDrawing",{e:a,coords:b}),this.ev.trigger("board:userAction"),a.stopPropagation(),a.preventDefault())},_onMouseOver:function(a,b){this.isMouseHovering=!0,this.coords.old=this._getInputCoords(a),this.coords.oldMid=this._getMidInputCoords(this.coords.old),this.ev.trigger("board:mouseOver",{e:a,coords:b})},_onMouseOut:function(a,b){this.isMouseHovering=!1,this.ev.trigger("board:mouseOut",{e:a,coords:b})},_getInputCoords:function(a){a=a.originalEvent?a.originalEvent:a;var b,c,d=this.canvas.getBoundingClientRect(),e=this.dom.$canvas.width(),f=this.dom.$canvas.height();return a.touches&&1==a.touches.length?(b=a.touches[0].pageX,c=a.touches[0].pageY):(b=a.pageX,c=a.pageY),b-=this.dom.$canvas.offset().left,c-=this.dom.$canvas.offset().top,b*=e/d.width,c*=f/d.height,{x:b,y:c}},_getMidInputCoords:function(a){return{x:this.coords.old.x+a.x>>1,y:this.coords.old.y+a.y>>1}}}; \ No newline at end of file diff --git a/js/board.js b/js/board.js index 9e65df2..45303d8 100644 --- a/js/board.js +++ b/js/board.js @@ -86,7 +86,8 @@ DrawingBoard.Board.defaultOpts = { droppable: false, enlargeYourContainer: false, errorMessage: "

It seems you use an obsolete browser. Update it to start drawing.

", - stretchImg: false //when setting the canvas img, strech the image at the whole canvas size when this opt is true + stretchImg: false, //when setting the canvas img, strech the image at the whole canvas size when this opt is true + keepImgRatio: true, // when stretch the image to the canvas size, keep image ratio when this opt is true }; @@ -309,6 +310,7 @@ DrawingBoard.Board.prototype = { setImg: function(src, opts) { opts = $.extend({ stretch: this.opts.stretchImg, + keepRatio: this.opts.keepImgRatio, callback: null }, opts); @@ -320,7 +322,18 @@ DrawingBoard.Board.prototype = { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); if (opts.stretch) { - ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); + if(opts.keepRatio) { + var canvasRatio = ctx.canvas.width / ctx.canvas.height; // measure of wide + var imgRatio = img.width / img.height; + var rWidth = ctx.canvas.width * (imgRatio / canvasRatio); + var rHeight = ctx.canvas.height * (canvasRatio / imgRatio); + if(canvasRatio > imgRatio) // canvas is more wide, keep height + ctx.drawImage(img, (ctx.canvas.width - rWidth) / 2, 0, rWidth, ctx.canvas.height); + else // canvas is more narrow, keep width + ctx.drawImage(img, 0, (ctx.canvas.height - rHeight) / 2, ctx.canvas.width, rHeight); + } else { + ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); + } } else { ctx.drawImage(img, 0, 0); }