/*! jCanvas v2.2.1 Caleb Evans 2.2.1 revisions by Thinkyhead */ (function($, document, Math, Number, undefined) { // jC global object var jC = {}; jC.originals = { width: 20, height: 20, cornerRadius: 0, fillStyle: 'transparent', strokeStyle: 'transparent', strokeWidth: 5, strokeCap: 'butt', strokeJoin: 'miter', shadowX: 0, shadowY: 0, shadowBlur: 10, shadowColor: 'transparent', x: 0, y: 0, x1: 0, y1: 0, radius: 10, start: 0, end: 360, ccw: false, inDegrees: true, fromCenter: true, closed: false, sides: 3, angle: 0, text: '', font: 'normal 12pt sans-serif', align: 'center', baseline: 'middle', source: '', repeat: 'repeat' }; // Duplicate original defaults jC.defaults = $.extend({}, jC.originals); // Set global properties function setGlobals(context, map) { context.fillStyle = map.fillStyle; context.strokeStyle = map.strokeStyle; context.lineWidth = map.strokeWidth; context.lineCap = map.strokeCap; context.lineJoin = map.strokeJoin; context.shadowOffsetX = map.shadowX; context.shadowOffsetY = map.shadowY; context.shadowBlur = map.shadowBlur; context.shadowColor = map.shadowColor; } // Close path if chosen function closePath(context, map) { if (map.closed === true) { context.closePath(); context.fill(); context.stroke(); } else { context.fill(); context.stroke(); context.closePath(); } } // Measure angles in degrees if chosen function checkUnits(map) { if (map.inDegrees === true) { return Math.PI / 180; } else { return 1; } } // Set canvas defaults $.fn.canvas = function(args) { // Reset defaults if no value is passed if (typeof args === 'undefined') { jC.defaults = jC.originals; } else { jC.defaults = $.extend({}, jC.defaults, args); } return this; }; // Load canvas $.fn.loadCanvas = function(context) { if (typeof context === 'undefined') {context = '2d';} return this[0].getContext(context); }; // Create gradient $.fn.gradient = function(args) { var ctx = this.loadCanvas(), // Specify custom defaults gDefaults = { x1: 0, y1: 0, x2: 0, y2: 0, r1: 10, r2: 100 }, params = $.extend({}, gDefaults, args), gradient, stops = 0, percent, i; // Create radial gradient if chosen if (typeof args.r1 === 'undefined' && typeof args.r2 === 'undefined') { gradient = ctx.createLinearGradient(params.x1, params.y1, params.x2, params.y2); } else { gradient = ctx.createRadialGradient(params.x1, params.y1, params.r1, params.x2, params.y2, params.r2); } // Count number of color stops for (i=1; i<=Number.MAX_VALUE; i+=1) { if (params['c' + i]) { stops += 1; } else { break; } } // Calculate color stop percentages if absent for (i=1; i<=stops; i+=1) { percent = Math.round((100 / (stops-1)) * (i-1)) / 100; if (typeof params['s' + i] === 'undefined') { params['s' + i] = percent; } gradient.addColorStop(params['s' + i], params['c' + i]); } return gradient; }; // Create pattern $.fn.pattern = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args), pattern, img = document.createElement('img'); img.src = params.source; // Create pattern function create() { if (img.complete === true) { // Create pattern pattern = ctx.createPattern(img, params.repeat); } else { throw "The pattern has not loaded yet"; } } try { create(); } catch(error) { img.onload = create; } return pattern; }; // Clear canvas $.fn.clearCanvas = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args); // Draw from center if chosen if (params.fromCenter === true) { params.x -= params.width / 2; params.y -= params.height / 2; } // Clear entire canvas if chosen ctx.beginPath(); if (typeof args === 'undefined') { ctx.clearRect(0, 0, this.width(), this.height()); } else { ctx.clearRect(params.x, params.y, params.width, params.height); } ctx.closePath(); return this; }; // Save canvas $.fn.saveCanvas = function() { var ctx = this.loadCanvas(); ctx.save(); return this; }; // Restore canvas $.fn.restoreCanvas = function() { var ctx = this.loadCanvas(); ctx.restore(); return this; }; // Scale canvas $.fn.scaleCanvas = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args); ctx.save(); ctx.translate(params.x, params.y); ctx.scale(params.width, params.height); ctx.translate(-params.x, -params.y) return this; }; // Translate canvas $.fn.translateCanvas = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args); ctx.save(); ctx.translate(params.x, params.y); return this; }; // Rotate canvas $.fn.rotateCanvas = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args), toRad = checkUnits(params); ctx.save(); ctx.translate(params.x, params.y); ctx.rotate(params.angle * toRad); ctx.translate(-params.x, -params.y); return this; }; // Draw rectangle $.fn.drawRect = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args), toRad = checkUnits(params), x1, y1, x2, y2, r; setGlobals(ctx, params); // Draw from center if chosen if (params.fromCenter === true) { params.x -= params.width / 2; params.y -= params.height / 2; } // Draw rounded rectangle if chosen if (params.cornerRadius > 0) { x1 = params.x; y1 = params.y; x2 = params.x + params.width; y2 = params.y + params.height; r = params.cornerRadius; if ((x2 - x1) - (2 * r) < 0) { r = (x2 - x1) / 2; } if ((y2 - y1) - (2 * r) < 0) { r = (y2 - y1) / 2; } ctx.beginPath(); ctx.moveTo(x1+r,y1); ctx.lineTo(x2-r,y1); ctx.arc(x2-r, y1+r, r, 270*toRad, 360*toRad, false); ctx.lineTo(x2,y2-r); ctx.arc(x2-r, y2-r, r, 0, 90*toRad, false); ctx.lineTo(x1+r,y2); ctx.arc(x1+r, y2-r, r, 90*toRad, 180*toRad, false); ctx.lineTo(x1,y1+r); ctx.arc(x1+r, y1+r, r, 180*toRad, 270*toRad, false); ctx.fill(); ctx.stroke(); ctx.closePath(); } else { ctx.fillRect(params.x, params.y, params.width, params.height); ctx.strokeRect(params.x, params.y, params.width, params.height); } return this; }; // Draw arc $.fn.drawArc = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args), toRad = checkUnits(params); setGlobals(ctx, params); // Draw from center if chosen if (params.fromCenter === false) { params.x += params.radius; params.y += params.radius; } ctx.beginPath(); ctx.arc(params.x, params.y, params.radius, (params.start*toRad)-(Math.PI/2), (params.end*toRad)-(Math.PI/2), params.ccw); // Close path if chosen closePath(ctx, params); return this; }; // Draw ellipse $.fn.drawEllipse = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args), controlW = params.width * (4/3); setGlobals(ctx, params); // Draw from center if chosen if (params.fromCenter === false) { params.x += params.width / 2; params.y += params.height / 2; } // Increment coordinates to prevent negative values params.x += 1e-10; params.y += 1e-10; // Create ellipse ctx.beginPath(); ctx.moveTo(params.x, params.y-params.height/2); ctx.bezierCurveTo(params.x-controlW/2,params.y-params.height/2, params.x-controlW/2,params.y+params.height/2, params.x,params.y+params.height/2); ctx.bezierCurveTo(params.x+controlW/2,params.y+params.height/2, params.x+controlW/2,params.y-params.height/2, params.x,params.y-params.height/2); ctx.closePath(); ctx.fill(); ctx.stroke(); return this; }; // Draw line $.fn.drawLine = function(args) { var ctx = this.loadCanvas(), params = $.extend({}, jC.defaults, args), max = Number.MAX_VALUE, l, lx, ly; setGlobals(ctx, params); // Draw each point ctx.beginPath(); ctx.moveTo(params.x1, params.y1); for (l=2; l= 3) { // Calculate points and draw theta = (Math.PI/2) + (Math.PI/params.sides) + (params.angle*toRad); dtheta = (Math.PI*2) / params.sides; for (i=0; i