/files/jquery.wpaint/1.13.1/wPaint.js
JavaScript | 978 lines | 712 code | 177 blank | 89 comment | 100 complexity | e610d579b606a6447fad657b89b0e439 MD5 | raw file
- /******************************************
- * Websanova.com
- *
- * Resources for web entrepreneurs
- *
- * @author Websanova
- * @copyright Copyright (c) 2012 Websanova.
- * @license This wPaint jQuery plug-in is dual licensed under the MIT and GPL licenses.
- * @link http://www.websanova.com
- * @github http://github.com/websanova/wPaint
- * @version Version 1.13.1
- *
- ******************************************/
- (function($)
- {
- $.fn.wPaint = function(option, settings)
- {
- if(typeof option === 'object')
- {
- settings = option;
- }
- else if(typeof option == 'string')
- {
- var values = [];
- var elements = this.each(function()
- {
- var data = $(this).data('_wPaint');
- if(data)
- {
- if(option == 'clear') { data.clearAll(); }
- else if(option == 'image' && settings === undefined) { values.push(data.getImage()); }
- else if(option == 'image' && settings !== undefined) { data.setImage(settings, true); }
- else if(option == 'imageBg' && settings !== undefined) { data.setBgImage(settings); }
- else if($.fn.wPaint.defaultSettings[option] !== undefined)
- {
- if(settings !== undefined) { data.settings[option] = settings; }
- else { values.push(data.settings[option]); }
- }
- }
- });
- if(values.length === 1) { return values[0]; }
- if(values.length > 0) { return values; }
- else { return elements; }
- }
- //clean up some variables
- settings = $.extend({}, $.fn.wPaint.defaultSettings, settings || {});
- settings.lineWidthMin = parseInt(settings.lineWidthMin);
- settings.lineWidthMax = parseInt(settings.lineWidthMax);
- settings.lineWidth = parseInt(settings.lineWidth);
- settings.fontSizeMin = parseInt(settings.fontSizeMin);
- settings.fontSizeMax = parseInt(settings.fontSizeMax);
- settings.fontSize = parseInt(settings.fontSize);
-
- return this.each(function()
- {
- var $elem = $(this);
- var _settings = jQuery.extend(true, {}, settings);
-
- //test for HTML5 canvas
- var test = document.createElement('canvas');
- if(!test.getContext)
- {
- $elem.html("Browser does not support HTML5 canvas, please upgrade to a more modern browser.");
- return false;
- }
-
- if($elem.data('_wPaint')) return false;
- var canvas = new Canvas(_settings, $elem);
- canvas.mainMenu = new MainMenu(canvas);
- canvas.textMenu = new TextMenu(canvas);
-
- if(_settings.imageBg) $elem.append(canvas.generateBg($elem.width(), $elem.height(), _settings.imageBg));
- $elem.append(canvas.generate($elem.width(), $elem.height()));
- $elem.append(canvas.generateTemp());
- $elem.append(canvas.generateTextInput());
- $elem
- .append(canvas.mainMenu.generate(canvas, canvas.textMenu))
- .append(canvas.textMenu.generate(canvas, canvas.mainMenu));
- //init the snap on the text menu
- canvas.mainMenu.moveTextMenu(canvas.mainMenu, canvas.textMenu);
- //init mode
- canvas.mainMenu.set_mode(canvas.mainMenu, canvas, _settings.mode);
- //pull from css so that it is dynamic
- var buttonSize = $("._wPaint_icon").outerHeight(true) - (parseInt($("._wPaint_icon").css('paddingTop').split('px')[0]) + parseInt($("._wPaint_icon").css('paddingBottom').split('px')[0]));
- canvas.mainMenu.menu.find("._wPaint_fillColorPicker").wColorPicker({
- mode: "click",
- initColor: _settings.fillStyle,
- buttonSize: buttonSize,
- showSpeed: 300,
- hideSpeed: 300,
- onSelect: function(color){
- canvas.settings.fillStyle = color;
- canvas.textInput.css({color: color});
- }
- });
-
- canvas.mainMenu.menu.find("._wPaint_strokeColorPicker").wColorPicker({
- mode: "click",
- initColor: _settings.strokeStyle,
- buttonSize: buttonSize,
- showSpeed: 300,
- hideSpeed: 300,
- onSelect: function(color){
- canvas.settings.strokeStyle = color;
- }
- });
-
- //must set width after append to get proper dimensions
- canvas.mainMenu.setWidth(canvas, canvas.mainMenu.menu);
- canvas.mainMenu.setWidth(canvas, canvas.textMenu.menu);
- if(_settings.image)
- {
- canvas.setImage(_settings.image, true);
- }
- else
- {
- canvas.addUndo();
- }
- $elem.data('_wPaint', canvas);
- });
- }
- var shapes = ['Rectangle', 'Ellipse', 'Line', 'Text'];
- $.fn.wPaint.defaultSettings = {
- mode : 'Pencil', // drawing mode - Rectangle, Ellipse, Line, Pencil, Eraser
- lineWidthMin : '0', // line width min for select drop down
- lineWidthMax : '10', // line widh max for select drop down
- lineWidth : '2', // starting line width
- fillStyle : '#FFFFFF', // starting fill style
- strokeStyle : '#FFFF00', // start stroke style
- fontSizeMin : '8', // min font size in px
- fontSizeMax : '20', // max font size in px
- fontSize : '12', // current font size for text input
- fontFamilyOptions : ['Arial', 'Courier', 'Times', 'Trebuchet', 'Verdana'], // available font families
- fontFamily : 'Arial', // active font family for text input
- fontTypeBold : false, // text input bold enable/disable
- fontTypeItalic : false, // text input italic enable/disable
- fontTypeUnderline : false, // text input italic enable/disable
- image : null, // preload image - base64 encoded data
- imageBg : null, // preload image bg, cannot be altered but saved with image
- drawDown : null, // function to call when start a draw
- drawMove : null, // function to call during a draw
- drawUp : null, // function to call at end of draw
- menu : ['undo', 'redo', 'clear','rectangle','ellipse','line','pencil','text','eraser','fillColor','lineWidth','strokeColor'], // menu items - appear in order they are set
- menuOrientation : 'horizontal', // orinetation of menu (horizontal, vertical)
- menuOffsetX : 5, // offset for menu (left)
- menuOffsetY : 5, // offset for menu (top)
- menuTitles : { // icon titles, replace any of the values to customize
- 'undo': 'undo',
- 'redo': 'redo',
- 'clear': 'clear',
- 'rectangle': 'rectangle',
- 'ellipse': 'ellipse',
- 'line': 'line',
- 'pencil': 'pencil',
- 'text': 'text',
- 'eraser': 'eraser',
- 'fillColor': 'fill color',
- 'lineWidth': 'line width',
- 'strokeColor': 'stroke color',
- 'bold': 'bold',
- 'italic': 'italic',
- 'underline': 'underline',
- 'fontSize': 'font size',
- 'fontFamily': 'font family'
- },
- disableMobileDefaults: false // disable default touchmove events for mobile (will prevent flipping between tabs and scrolling)
- };
- /**
- * Canvas class definition
- */
- function Canvas(settings, elem)
- {
- this.settings = settings;
- this.$elem = elem;
- this.mainMenu = null;
- this.textMenu = null;
-
- this.undoArray = [];
- this.undoCurrent = -1;
- this.undoMax = 10;
- this.draw = false;
- this.canvas = null;
- this.ctx = null;
- this.canvasTemp = null;
- this.ctxTemp = null;
-
- this.canvasBg = null;
- this.ctxBg = null;
- this.canvasTempLeftOriginal = null;
- this.canvasTempTopOriginal = null;
-
- this.canvasTempLeftNew = null;
- this.canvasTempTopNew = null;
-
- this.textInput = null;
-
- return this;
- }
-
- Canvas.prototype =
- {
- /*******************************************************************************
- * Generate canvases and events
- *******************************************************************************/
- generate: function(width, height)
- {
- this.canvas = document.createElement('canvas');
- this.ctx = this.canvas.getContext('2d');
-
- //create local reference
- var _self = this;
-
- $(this.canvas)
- .attr('width', width + 'px')
- .attr('height', height + 'px')
- .css({position: 'absolute', left: 0, top: 0})
- .mousedown(function(e)
- {
- e.preventDefault();
- e.stopPropagation();
- _self.draw = true;
- _self.callFunc(e, _self, 'Down');
- });
-
- $(document)
- .mousemove(function(e)
- {
- if(_self.draw) _self.callFunc(e, _self, 'Move');
- })
- .mouseup(function(e)
- {
- //make sure we are in draw mode otherwise this will fire on any mouse up.
- if(_self.draw)
- {
- _self.draw = false;
- _self.callFunc(e, _self, 'Up');
- }
- });
-
- this.bindMobile();
- return $(this.canvas);
- },
- bindMobile: function()
- {
- $(this.canvas).bind('touchstart touchmove touchend touchcancel', function ()
- {
- var touches = event.changedTouches, first = touches[0], type = "";
- switch (event.type)
- {
- case "touchstart": type = "mousedown"; break;
- case "touchmove": type = "mousemove"; break;
- case "touchend": type = "mouseup"; break;
- default: return;
- }
- var simulatedEvent = document.createEvent("MouseEvent");
- simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null);
- first.target.dispatchEvent(simulatedEvent);
- event.preventDefault();
- });
- //eliminate browser defaults for
- if(this.settings.disableMobileDefaults) $(document).bind('touchmove', function(e) { e.preventDefault(); });
- },
-
- generateTemp: function()
- {
- this.canvasTemp = document.createElement('canvas');
- this.ctxTemp = this.canvasTemp.getContext('2d');
-
- $(this.canvasTemp).css({position: 'absolute'}).hide();
-
- return $(this.canvasTemp);
- },
- generateBg: function(width, height, data)
- {
- var _self = this;
-
- if(!this.canvasBg)
- {
- this.canvasBg = document.createElement('canvas');
- this.ctxBg = this.canvasBg.getContext('2d');
- $(this.canvasBg).attr('id', 'mofo').css({position: 'absolute', left: 0, top: 0}).attr('width', width).attr('height', height);
- }
-
- this.setBgImage(data);
- return $(this.canvasBg);
- },
-
- generateTextInput: function()
- {
- var _self = this;
-
- _self.textCalc = $('<div></div>').css({display:'none', fontSize:this.settings.fontSize, lineHeight:this.settings.fontSize+'px', fontFamily:this.settings.fontFamily});
-
- _self.textInput =
- $('<textarea class="_wPaint_textInput" spellcheck="false"></textarea>')
- .css({display:'none', position:'absolute', color:this.settings.fillStyle, fontSize:this.settings.fontSize, lineHeight:this.settings.fontSize+'px', fontFamily:this.settings.fontFamily})
- if(_self.settings.fontTypeBold) { _self.textInput.css('fontWeight', 'bold'); _self.textCalc.css('fontWeight', 'bold'); }
- if(_self.settings.fontTypeItalic) { _self.textInput.css('fontStyle', 'italic'); _self.textCalc.css('fontStyle', 'italic'); }
- if(_self.settings.fontTypeUnderline) { _self.textInput.css('textDecoration', 'underline'); _self.textCalc.css('textDecoration', 'underline'); }
-
- $('body').append(_self.textCalc);
-
- return _self.textInput;
- },
-
- callFunc: function(e, _self, event)
- {
- $e = jQuery.extend(true, {}, e);
-
- var canvas_offset = $(_self.canvas).offset();
-
- $e.pageX = Math.floor($e.pageX - canvas_offset.left);
- $e.pageY = Math.floor($e.pageY - canvas_offset.top);
-
- var mode = $.inArray(_self.settings.mode, shapes) > -1 ? 'Shape' : _self.settings.mode;
- var func = _self['draw' + mode + '' + event];
-
- if(func) func($e, _self);
- if(_self.settings['draw' + event]) _self.settings['draw' + event].apply(_self, [e, mode]);
- if(_self.settings.mode !== 'Text' && event === 'Up') { this.addUndo(); }
- },
-
- /*******************************************************************************
- * draw any shape
- *******************************************************************************/
- drawShapeDown: function(e, _self)
- {
- if(_self.settings.mode == 'Text')
- {
- //draw current text before resizing next text box
- if(_self.textInput.val() != '') _self.drawTextUp(e, _self);
-
- _self.textInput.css({left: e.pageX-1, top: e.pageY-1, width:0, height:0});
- }
- $(_self.canvasTemp)
- .css({left: e.pageX, top: e.pageY})
- .attr('width', 0)
- .attr('height', 0)
- .show();
- _self.canvasTempLeftOriginal = e.pageX;
- _self.canvasTempTopOriginal = e.pageY;
-
- var func = _self['draw' + _self.settings.mode + 'Down'];
-
- if(func) func(e, _self);
- },
-
- drawShapeMove: function(e, _self)
- {
- var xo = _self.canvasTempLeftOriginal;
- var yo = _self.canvasTempTopOriginal;
-
- var half_line_width = _self.settings.lineWidth / 2;
-
- var left = (e.pageX < xo ? e.pageX : xo) - (_self.settings.mode == 'Line' ? Math.floor(half_line_width) : 0);
- var top = (e.pageY < yo ? e.pageY : yo) - (_self.settings.mode == 'Line' ? Math.floor(half_line_width) : 0);
- var width = Math.abs(e.pageX - xo) + (_self.settings.mode == 'Line' ? _self.settings.lineWidth : 0);
- var height = Math.abs(e.pageY - yo) + (_self.settings.mode == 'Line' ? _self.settings.lineWidth : 0);
- $(_self.canvasTemp)
- .css({left: left, top: top})
- .attr('width', width)
- .attr('height', height)
-
- if(_self.settings.mode == 'Text') _self.textInput.css({left: left-1, top: top-1, width:width, height:height});
-
- _self.canvasTempLeftNew = left;
- _self.canvasTempTopNew = top;
-
- var func = _self['draw' + _self.settings.mode + 'Move'];
-
- if(func)
- {
- var factor = _self.settings.mode == 'Line' ? 1 : 2;
-
- e.x = half_line_width*factor;
- e.y = half_line_width*factor;
- e.w = width - _self.settings.lineWidth*factor;
- e.h = height - _self.settings.lineWidth*factor;
-
- _self.ctxTemp.fillStyle = _self.settings.fillStyle;
- _self.ctxTemp.strokeStyle = _self.settings.strokeStyle;
- _self.ctxTemp.lineWidth = _self.settings.lineWidth*factor;
-
- func(e, _self);
- }
- },
-
- drawShapeUp: function(e, _self)
- {
- if(_self.settings.mode != 'Text')
- {
- _self.ctx.drawImage(_self.canvasTemp ,_self.canvasTempLeftNew, _self.canvasTempTopNew);
-
- $(_self.canvasTemp).hide();
-
- var func = _self['draw' + _self.settings.mode + 'Up'];
- if(func) func(e, _self);
- }
- },
-
- /*******************************************************************************
- * draw rectangle
- *******************************************************************************/
- drawRectangleMove: function(e, _self)
- {
- _self.ctxTemp.beginPath();
- _self.ctxTemp.rect(e.x, e.y, e.w, e.h)
- _self.ctxTemp.closePath();
- _self.ctxTemp.stroke();
- _self.ctxTemp.fill();
- },
-
- /*******************************************************************************
- * draw ellipse
- *******************************************************************************/
- drawEllipseMove: function(e, _self)
- {
- var kappa = .5522848;
- var ox = (e.w / 2) * kappa; // control point offset horizontal
- var oy = (e.h / 2) * kappa; // control point offset vertical
- var xe = e.x + e.w; // x-end
- var ye = e.y + e.h; // y-end
- var xm = e.x + e.w / 2; // x-middle
- var ym = e.y + e.h / 2; // y-middle
-
- _self.ctxTemp.beginPath();
- _self.ctxTemp.moveTo(e.x, ym);
- _self.ctxTemp.bezierCurveTo(e.x, ym - oy, xm - ox, e.y, xm, e.y);
- _self.ctxTemp.bezierCurveTo(xm + ox, e.y, xe, ym - oy, xe, ym);
- _self.ctxTemp.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
- _self.ctxTemp.bezierCurveTo(xm - ox, ye, e.x, ym + oy, e.x, ym);
- _self.ctxTemp.closePath();
- if(_self.settings.lineWidth > 0)_self.ctxTemp.stroke();
- _self.ctxTemp.fill();
- },
-
- /*******************************************************************************
- * draw line
- *******************************************************************************/
- drawLineMove: function(e, _self)
- {
- var xo = _self.canvasTempLeftOriginal;
- var yo = _self.canvasTempTopOriginal;
-
- if(e.pageX < xo) { e.x = e.x + e.w; e.w = e.w * -1}
- if(e.pageY < yo) { e.y = e.y + e.h; e.h = e.h * -1}
-
- _self.ctxTemp.lineJoin = "round";
- _self.ctxTemp.beginPath();
- _self.ctxTemp.moveTo(e.x, e.y);
- _self.ctxTemp.lineTo(e.x + e.w, e.y + e.h);
- _self.ctxTemp.closePath();
- _self.ctxTemp.stroke();
- },
-
- /*******************************************************************************
- * draw pencil
- *******************************************************************************/
- drawPencilDown: function(e, _self)
- {
- _self.ctx.lineJoin = "round";
- _self.ctx.lineCap = "round";
- _self.ctx.strokeStyle = _self.settings.strokeStyle;
- _self.ctx.fillStyle = _self.settings.strokeStyle;
- _self.ctx.lineWidth = _self.settings.lineWidth;
-
- //draw single dot in case of a click without a move
- _self.ctx.beginPath();
- _self.ctx.arc(e.pageX, e.pageY, _self.settings.lineWidth/2, 0, Math.PI*2, true);
- _self.ctx.closePath();
- _self.ctx.fill();
-
- //start the path for a drag
- _self.ctx.beginPath();
- _self.ctx.moveTo(e.pageX, e.pageY);
- },
-
- drawPencilMove: function(e, _self)
- {
- _self.ctx.lineTo(e.pageX, e.pageY);
- _self.ctx.stroke();
- },
-
- drawPencilUp: function(e, _self)
- {
- _self.ctx.closePath();
- },
- /*******************************************************************************
- * draw text
- *******************************************************************************/
-
- drawTextDown: function(e, _self)
- {
- _self.textInput.val('').show().focus();
- },
-
- drawTextUp: function(e, _self)
- {
- if(e) { this.addUndo(); }
- var fontString = '';
- if(_self.settings.fontTypeItalic) fontString += 'italic ';
- //if(_self.settings.fontTypeUnderline) fontString += 'underline ';
- if(_self.settings.fontTypeBold) fontString += 'bold ';
-
- fontString += _self.settings.fontSize + 'px ' + _self.settings.fontFamily;
-
- //setup lines
- var lines = _self.textInput.val().split('\n');
- var linesNew = [];
- var textInputWidth = _self.textInput.width() - 2;
-
- var width = 0;
- var lastj = 0;
-
- for(var i=0, ii=lines.length; i<ii; i++)
- {
- _self.textCalc.html('');
- lastj = 0;
-
- for(var j=0, jj=lines[0].length; j<jj; j++)
- {
- width = _self.textCalc.append(lines[i][j]).width();
-
- if(width > textInputWidth)
- {
- linesNew.push(lines[i].substring(lastj,j));
- lastj = j;
- _self.textCalc.html(lines[i][j]);
- }
- }
-
- if(lastj != j) linesNew.push(lines[i].substring(lastj,j));
- }
-
- lines = _self.textInput.val(linesNew.join('\n')).val().split('\n');
-
- var offset = _self.textInput.position();
- var left = offset.left;
- var top = offset.top;
- var underlineOffset = 0;
-
- for(var i=0, ii=lines.length; i<ii; i++)
- {
- _self.ctx.fillStyle = _self.settings.fillStyle;
-
- _self.ctx.textBaseline = 'top';
- _self.ctx.font = fontString;
- _self.ctx.fillText(lines[i], left, top);
-
- top += _self.settings.fontSize;
-
- if(lines[i] != '' && _self.settings.fontTypeUnderline)
- {
- width = _self.textCalc.html(lines[i]).width();
-
- //manually set pixels for underline since to avoid antialiasing 1px issue, and lack of support for underline in canvas
- var imgData = _self.ctx.getImageData(0, top+underlineOffset, width, 1);
-
- for (j=0; j<imgData.width*imgData.height*4; j+=4)
- {
- imgData.data[j] = parseInt(_self.settings.fillStyle.substring(1,3), 16);
- imgData.data[j+1] = parseInt(_self.settings.fillStyle.substring(3,5), 16);
- imgData.data[j+2] = parseInt(_self.settings.fillStyle.substring(5,7), 16);
- imgData.data[j+3] = 255;
- }
-
- _self.ctx.putImageData(imgData, left, top+underlineOffset);
- }
- }
- },
-
- /*******************************************************************************
- * eraser
- *******************************************************************************/
- drawEraserDown: function(e, _self)
- {
- _self.ctx.save();
- _self.ctx.globalCompositeOperation = 'destination-out';
- _self.drawPencilDown(e, _self);
- },
-
- drawEraserMove: function(e, _self)
- {
- _self.drawPencilMove(e, _self);
- },
-
- drawEraserUp: function(e, _self)
- {
- _self.drawPencilUp(e, _self);
- _self.ctx.restore();
- },
- /*******************************************************************************
- * save / load data
- *******************************************************************************/
- getImage: function()
- {
- this.canvasSave = document.createElement('canvas');
- this.ctxSave = this.canvasSave.getContext('2d');
- $(this.canvasSave).css({display:'none', position: 'absolute', left: 0, top: 0}).attr('width', $(this.canvas).attr('width')).attr('height', $(this.canvas).attr('height'));
- //if a bg image is set, it will automatically save with the image
- if(this.canvasBg) this.ctxSave.drawImage(this.canvasBg, 0, 0);
- this.ctxSave.drawImage(this.canvas, 0, 0);
- return this.canvasSave.toDataURL();
- },
-
- setImage: function(data, addUndo)
- {
- var _self = this;
-
- var myImage = new Image();
- myImage.src = data.toString();
- _self.ctx.clearRect(0, 0, _self.canvas.width, _self.canvas.height);
-
- $(myImage).load(function(){
- _self.ctx.drawImage(myImage, 0, 0);
- if(addUndo) { _self.addUndo(); }
- });
- },
- setBgImage: function(data, addUndo)
- {
- var _self = this;
- var myImage = new Image();
- myImage.src = data.toString();
- _self.ctxBg.clearRect(0, 0, _self.canvasBg.width, _self.canvasBg.height);
-
- $(myImage).load(function()
- {
- _self.ctxBg.drawImage(myImage, 0, 0);
- });
- },
- /*******************************************************************************
- * undo / redo
- *******************************************************************************/
- addUndo: function()
- {
- //if it's not at the end of the array we need to repalce the current array position
- if(this.undoCurrent < this.undoArray.length-1)
- {
- this.undoArray[++this.undoCurrent] = this.getImage();
- }
- else // owtherwise we push normally here
- {
- this.undoArray.push(this.getImage());
- //if we're at the end of the array we need to slice off the front - in increment required
- if(this.undoArray.length > this.undoMax){ this.undoArray = this.undoArray.slice(1, this.undoArray.length); }
- //if we're NOT at the end of the array, we just increment
- else{ this.undoCurrent++; }
- }
- //for undo's then a new draw we want to remove everything afterwards - in most cases nothing will happen here
- while(this.undoCurrent != this.undoArray.length-1) { this.undoArray.pop(); }
- this.undoToggleIcons();
- },
- setUndoImage: function()
- {
- this.setImage(this.undoArray[this.undoCurrent]);
- },
- undoNext: function()
- {
- if(this.undoArray[this.undoCurrent+1]) { this.undoCurrent++; this.setUndoImage(); }
- this.undoToggleIcons();
- },
- undoPrev: function()
- {
- if(this.undoArray[this.undoCurrent-1]) { this.undoCurrent--; this.setUndoImage(); }
- this.undoToggleIcons();
- },
- undoToggleIcons: function()
- {
- var iconUndo = this.mainMenu.menu.find("._wPaint_undo");
- var iconRedo = this.mainMenu.menu.find("._wPaint_redo");
- if(this.undoCurrent > 0 && this.undoArray.length > 1)
- {
- if(!iconUndo.hasClass('uactive')) { iconUndo.addClass('uactive'); }
- }
- else { iconUndo.removeClass('uactive'); }
- if(this.undoCurrent < this.undoArray.length-1)
- {
- if(!iconRedo.hasClass('uactive')) { iconRedo.addClass('uactive'); }
- }
- else { iconRedo.removeClass('uactive'); }
- },
- /*******************************************************************************
- * Functions
- *******************************************************************************/
- clearAll: function()
- {
- this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
- this.addUndo();
- }
- }
-
- /**
- * Main Menu
- */
- function MainMenu(canvas)
- {
- this.menu = null;
-
- return this;
- }
-
- MainMenu.prototype =
- {
- generate: function(canvas, textMenu)
- {
- var $canvas = canvas;
- this.textMenu = textMenu;
- var _self = this;
-
- //setup the line width select
- var options = '';
- for(var i=$canvas.settings.lineWidthMin; i<=$canvas.settings.lineWidthMax; i++) options += '<option value="' + i + '" ' + ($canvas.settings.lineWidth == i ? 'selected="selected"' : '') + '>' + i + '</option>';
-
- var lineWidth = $('<div class="_wPaint_lineWidth _wPaint_dropDown" title="' + $canvas.settings.menuTitles.lineWidth + '"></div>').append(
- $('<select>' + options + '</select>')
- .change(function(e){ $canvas.settings.lineWidth = parseInt($(this).val()); })
- )
-
- //content
- var menuContent = $('<div class="_wPaint_options"></div>');
-
- $.each($canvas.settings.menu, function(i, item)
- {
- switch(item)
- {
- case 'undo': menuContent.append($('<div class="_wPaint_icon _wPaint_undo" title="' + $canvas.settings.menuTitles.undo + '"></div>').click(function(){ $canvas.undoPrev(); })); break;
- case 'redo': menuContent.append($('<div class="_wPaint_icon _wPaint_redo" title="' + $canvas.settings.menuTitles.redo + '"></div>').click(function(){ $canvas.undoNext(); })); break;
- case 'clear': menuContent.append($('<div class="_wPaint_icon _wPaint_clear" title="' + $canvas.settings.menuTitles.clear + '"></div>').click(function(){ $canvas.clearAll(); })); break;
- case 'rectangle': menuContent.append($('<div class="_wPaint_icon _wPaint_rectangle" title="' + $canvas.settings.menuTitles.rectangle + '"></div>').click(function(){ _self.set_mode(_self, $canvas, 'Rectangle'); })); break;
- case 'ellipse': menuContent.append($('<div class="_wPaint_icon _wPaint_ellipse" title="' + $canvas.settings.menuTitles.ellipse + '"></div>').click(function(){ _self.set_mode(_self, $canvas, 'Ellipse'); })); break;
- case 'line': menuContent.append($('<div class="_wPaint_icon _wPaint_line" title="' + $canvas.settings.menuTitles.line + '"></div>').click(function(){ _self.set_mode(_self, $canvas, 'Line'); })); break;
- case 'pencil': menuContent.append($('<div class="_wPaint_icon _wPaint_pencil" title="' + $canvas.settings.menuTitles.pencil + '"></div>').click(function(){ _self.set_mode(_self, $canvas, 'Pencil'); })); break;
- case 'text': menuContent.append($('<div class="_wPaint_icon _wPaint_text" title="' + $canvas.settings.menuTitles.text + '"></div>').click(function(){ _self.set_mode(_self, $canvas, 'Text'); })); break;
- case 'eraser': menuContent.append($('<div class="_wPaint_icon _wPaint_eraser" title="' + $canvas.settings.menuTitles.eraser + '"></div>').click(function(e){ _self.set_mode(_self, $canvas, 'Eraser'); })); break;
- case 'fillColor': menuContent.append($('<div class="_wPaint_fillColorPicker _wPaint_colorPicker" title="' + $canvas.settings.menuTitles.fillColor + '"></div>')); break;
- case 'lineWidth': menuContent.append(lineWidth); break;
- case 'strokeColor': menuContent.append($('<div class="_wPaint_strokeColorPicker _wPaint_colorPicker" title="' + $canvas.settings.menuTitles.strokeColor + 'r"></div>')); break;
- }
- });
- //handle
- var menuHandle = $('<div class="_wPaint_handle"></div>')
-
- //get position of canvas
- //var offset = $($canvas.canvas).offset();
-
- //menu
- return this.menu =
- $('<div class="_wPaint_menu _wPaint_menu_' + $canvas.settings.menuOrientation + '"></div>')
- .css({position: 'absolute', left: $canvas.settings.menuOffsetX, top: $canvas.settings.menuOffsetY})
- .draggable({
- handle: menuHandle,
- drag: function(){_self.moveTextMenu(_self, _self.textMenu)},
- stop: function(){_self.moveTextMenu(_self, _self.textMenu)}
- })
- .append(menuHandle)
- .append(menuContent);
- },
-
- moveTextMenu: function(mainMenu, textMenu)
- {
- if(textMenu.docked)
- {
- textMenu.menu.css({left: parseInt(mainMenu.menu.css('left')) + textMenu.dockOffsetLeft, top: parseInt(mainMenu.menu.css('top')) + textMenu.dockOffsetTop});
- }
- },
-
- set_mode: function(_self, $canvas, mode)
- {
- $canvas.settings.mode = mode;
-
- if(mode == 'Text')
- {
- _self.textMenu.menu.show();
- _self.setWidth($canvas, _self.textMenu.menu);
- }
- else
- {
- $canvas.drawTextUp(null, $canvas);
- _self.textMenu.menu.hide();
- $canvas.textInput.hide();
- }
-
- _self.menu.find("._wPaint_icon").removeClass('active');
- _self.menu.find("._wPaint_" + mode.toLowerCase()).addClass('active');
- },
- setWidth: function(canvas, menu)
- {
- var options = menu.find('._wPaint_options');
- if(canvas.settings.menuOrientation === 'vertical')
- {
- // set proper width
- var width = menu.find('._wPaint_options > div:first').outerWidth(true);
- width += (options.outerWidth(true) - options.width());
- //set proper height
- }
- else
- {
- var width = menu.find('._wPaint_handle').outerWidth(true);
- width += menu.outerWidth(true) - menu.width();
-
- menu.find('._wPaint_options').children().each(function()
- {
- width += $(this).outerWidth(true);
- });
- }
- menu.width(width);
- }
- }
-
- /**
- * Text Helper
- */
- function TextMenu(canvas)
- {
- this.menu = null;
-
- this.docked = true;
-
- this.dockOffsetLeft = canvas.settings.menuOrientation === 'vertical' ? 36 : 0;
- this.dockOffsetTop = canvas.settings.menuOrientation === 'vertical' ? 0 : 36;
-
- return this;
- }
-
- TextMenu.prototype =
- {
- generate: function(canvas, mainMenu)
- {
- var $canvas = canvas;
- var _self = this;
-
- //setup font sizes
- var options = '';
- for(var i=$canvas.settings.fontSizeMin; i<=$canvas.settings.fontSizeMax; i++) options += '<option value="' + i + '" ' + ($canvas.settings.fontSize == i ? 'selected="selected"' : '') + '>' + i + '</option>';
-
- var fontSize = $('<div class="_wPaint_fontSize _wPaint_dropDown" title="' + $canvas.settings.menuTitles.fontSize + '"></div>').append(
- $('<select>' + options + '</select>')
- .change(function(e){
- var fontSize = parseInt($(this).val());
- $canvas.settings.fontSize = fontSize;
- $canvas.textInput.css({fontSize:fontSize, lineHeight:fontSize+'px'});
- $canvas.textCalc.css({fontSize:fontSize, lineHeight:fontSize+'px'});
- })
- )
-
- //setup font family
- var options = '';
- for(var i=0, ii=$canvas.settings.fontFamilyOptions.length; i<ii; i++) options += '<option value="' + $canvas.settings.fontFamilyOptions[i] + '" ' + ($canvas.settings.fontFamily == $canvas.settings.fontFamilyOptions[i] ? 'selected="selected"' : '') + '>' + $canvas.settings.fontFamilyOptions[i] + '</option>';
-
- var fontFamily = $('<div class="_wPaint_fontFamily _wPaint_dropDown" title="' + $canvas.settings.menuTitles.fontFamily + '"><div class="_wPaint_dropDown_cover"></div></div>').append(
- $('<select>' + options + '</select>')
- .change(function(e){
- var fontFamily = $(this).val();
- $canvas.settings.fontFamily = fontFamily;
- $canvas.textInput.css({fontFamily: fontFamily});
- $canvas.textCalc.css({fontFamily: fontFamily});
- })
- )
-
- //content
- var menuContent =
- $('<div class="_wPaint_options"></div>')
- .append($('<div class="_wPaint_icon _wPaint_bold ' + ($canvas.settings.fontTypeBold ? 'active' : '') + '" title="' + $canvas.settings.menuTitles.bold + '"></div>').click(function(){ _self.setType(_self, $canvas, 'Bold'); }))
- .append($('<div class="_wPaint_icon _wPaint_italic ' + ($canvas.settings.fontTypeItalic ? 'active' : '') + '" title="' + $canvas.settings.menuTitles.italic + '"></div>').click(function(){ _self.setType(_self, $canvas, 'Italic'); }))
- .append($('<div class="_wPaint_icon _wPaint_underline ' + ($canvas.settings.fontTypeUnderline ? 'active' : '') + '" title="' + $canvas.settings.menuTitles.underline + '"></div>').click(function(){ _self.setType(_self, $canvas, 'Underline'); }))
- .append(fontSize)
- .append(fontFamily);
-
- //handle
- var menuHandle = $('<div class="_wPaint_handle"></div>')
-
- //get position of canvas
- var offset = $($canvas.canvas).offset();
-
- //menu
- return this.menu =
- $('<div class="_wPaint_menu _wPaint_menu_' + $canvas.settings.menuOrientation + '""></div>')
- .css({display: 'none', position: 'absolute'})
- .draggable({
- snap: '._wPaint_menu',
- handle: menuHandle,
- stop: function(){
- $.each($(this).data('draggable').snapElements, function(index, element){
- _self.dockOffsetLeft = _self.menu.offset().left - mainMenu.menu.offset().left;
- _self.dockOffsetTop = _self.menu.offset().top - mainMenu.menu.offset().top;
- _self.docked = element.snapping;
- });
- }
- })
- .append(menuHandle)
- .append(menuContent);
- },
-
- setType: function(_self, $canvas, mode)
- {
- var element = _self.menu.find("._wPaint_" + mode.toLowerCase());
- var isActive = element.hasClass('active')
-
- $canvas.settings['fontType' + mode] = !isActive;
-
- isActive ? element.removeClass('active') : element.addClass('active');
-
- fontTypeBold = $canvas.settings.fontTypeBold ? 'bold' : 'normal';
- fontTypeItalic = $canvas.settings.fontTypeItalic ? 'italic' : 'normal';
- fontTypeUnderline = $canvas.settings.fontTypeUnderline ? 'underline' : 'none';
-
- $canvas.textInput.css({fontWeight: fontTypeBold}); $canvas.textCalc.css({fontWeight: fontTypeBold});
- $canvas.textInput.css({fontStyle: fontTypeItalic}); $canvas.textCalc.css({fontStyle: fontTypeItalic});
- $canvas.textInput.css({textDecoration: fontTypeUnderline}); $canvas.textCalc.css({textDecoration: fontTypeUnderline});
- }
- }
- })(jQuery);