Skip to content
This repository
Browse code

Rewrote the jCanvas gradient algorithm to match the CSS gradient algo…

…rithm.
  • Loading branch information...
commit 5d5d325a633121ed0db597c6f5dfdf793758c04a 1 parent 44d7130
Caleb Evans authored March 31, 2012
739  jcanvas.js
@@ -15,20 +15,21 @@ var defaults, prefs,
15 15
 	sin = Math.sin,
16 16
 	cos = Math.cos,
17 17
 	eventFix = $.event.fix,
18  
-	_event = {},
19  
-	cssProps, colorProps;
  18
+	eventCache = {},
  19
+	cssProps,
  20
+	colorProps;
20 21
 
21 22
 // Preferences constructor
22 23
 function Prefs() {}
23 24
 
24 25
 // jCanvas function
25 26
 function jCanvas(args) {
26  
-	if (!args) {
27  
-		// Reset to defaults if nothing is passed
28  
-		prefs = Prefs.prototype = merge({}, defaults);
29  
-	} else {
  27
+	if (args) {
30 28
 		// Merge arguments with preferences
31 29
 		merge(prefs, args);
  30
+	} else {
  31
+		// Reset to defaults if nothing is passed
  32
+		prefs = Prefs.prototype = merge({}, defaults);
32 33
 	}
33 34
 	return this;
34 35
 }
@@ -52,7 +53,7 @@ defaults = {
52 53
 	fillStyle: 'transparent',
53 54
 	font: '12pt sans-serif',
54 55
 	fromCenter: TRUE,
55  
-	height: null,
  56
+	height: NULL,
56 57
 	inDegrees: TRUE,
57 58
 	load: NULL,
58 59
 	mask: FALSE,
@@ -81,7 +82,8 @@ defaults = {
81 82
 	sx: NULL,
82 83
 	sy: NULL,
83 84
 	text: '',
84  
-	width: null,
  85
+	visible: TRUE,
  86
+	width: NULL,
85 87
 	x: 0,
86 88
 	x1: 0,
87 89
 	x2: 0,
@@ -118,9 +120,9 @@ function setGlobals(ctx, params) {
118 120
 function createEvent(name) {
119 121
 	jCanvas.events[name] = function($elem) {
120 122
 		$elem.unbind(name + '.jCanvas').bind(name + '.jCanvas', function(event) {
121  
-			_event.x = event.offsetX;
122  
-			_event.y = event.offsetY;
123  
-			_event.type = event.type;
  123
+			eventCache.x = event.offsetX;
  124
+			eventCache.y = event.offsetY;
  125
+			eventCache.type = event.type;
124 126
 			$elem.drawLayers();
125 127
 		});
126 128
 	};
@@ -133,12 +135,12 @@ createEvent('mousemove');
133 135
 
134 136
 // Check if event fires when a drawing is drawn
135 137
 function checkEvents(ctx, params) {
136  
-	var callback = params[_event.type];
137  
-	if (_event.type && callback && ctx.isPointInPath(_event.x, _event.y)) {
138  
-		params.mouseX = _event.x;
139  
-		params.mouseY = _event.y;
140  
-		_event.x = UNDEFINED;
141  
-		_event.y = UNDEFINED;
  138
+	var callback = params[eventCache.type];
  139
+	if (eventCache.type && callback && ctx.isPointInPath(eventCache.x, eventCache.y)) {
  140
+		params.mouseX = eventCache.x;
  141
+		params.mouseY = eventCache.y;
  142
+		eventCache.x = UNDEFINED;
  143
+		eventCache.y = UNDEFINED;
142 144
 		callback.call(this, params);
143 145
 		setGlobals(ctx, params);
144 146
 	}
@@ -168,15 +170,11 @@ function closePath(ctx, params) {
168 170
 	}
169 171
 }
170 172
 
171  
-// Measure angles in chosen units
172  
-function convertAngles(params) {
173  
-	return (params.inDegrees ? PI/180 : 1);
174  
-}
175  
-
176 173
 // Rotate individual shape
177 174
 function positionShape(ctx, params, width, height) {
178 175
 	
179  
-	params.toRad = convertAngles(params);
  176
+	// Measure angles in chosen units
  177
+	params.toRad = (params.inDegrees ? PI/180 : 1);
180 178
 	ctx.save();
181 179
 		
182 180
 	// Always rotate from center
@@ -210,11 +208,10 @@ function extend(plugin) {
210 208
 			for (e=0; e<$elems.length; e+=1) {
211 209
 				elem = $elems[e];
212 210
 				ctx = loadCanvas(elem);
213  
-				if (!ctx) {continue;}
214  
-				
215  
-				setGlobals(ctx, params);
216  
-				params.toRad = convertAngles(params);
217  
-				plugin.fn.call(elem, ctx, params);
  211
+				if (ctx) {
  212
+					setGlobals(ctx, params);
  213
+					plugin.fn.call(elem, ctx, params);
  214
+				}
218 215
 			}
219 216
 			return $elems;
220 217
 		};
@@ -231,6 +228,7 @@ $.fn.loadCanvas = function() {
231 228
 $.fn.getCanvasImage = function(type) {
232 229
 	var elem = this[0];
233 230
 	if (!elem || !elem.toDataURL) {return NULL;}
  231
+	
234 232
 	if (type === UNDEFINED) {
235 233
 		type = 'image/png';
236 234
 	} else {
@@ -249,9 +247,9 @@ $.fn.draw = function(callback) {
249 247
 	
250 248
 	for (e=0; e<$elems.length; e+=1) {
251 249
 		ctx = loadCanvas($elems[e]);
252  
-		if (!ctx) {continue;}
253  
-		
254  
-		callback.call($elems[e], ctx);
  250
+		if (ctx) {
  251
+			callback.call($elems[e], ctx);
  252
+		}
255 253
 	}
256 254
 	return $elems;
257 255
 };
@@ -260,33 +258,50 @@ $.fn.draw = function(callback) {
260 258
 $.fn.gradient = function(args) {
261 259
 	var $elems = this,
262 260
 		ctx, params = merge(new Prefs(), args),
263  
-		gradient, percent,
  261
+		gradient,
264 262
 		stops = 0,
265  
-		i = 1;
  263
+		start = 0, end = 100,
  264
+		i = 1, last;
266 265
 	
267 266
 	ctx = loadCanvas($elems[0]);
268  
-	if (!ctx) {return NULL;}
269  
-	
270  
-	// Create radial gradient if chosen
271  
-	if (params.r1 !== NULL || params.r2 !== NULL) {
272  
-		gradient = ctx.createRadialGradient(params.x1, params.y1, params.r1, params.x2, params.y2, params.r2);
273  
-	} else {
274  
-		gradient = ctx.createLinearGradient(params.x1, params.y1, params.x2, params.y2);
275  
-	}
  267
+	if (ctx) {
276 268
 	
277  
-	// Count number of color stops
278  
-	while (params['c' + i] !== UNDEFINED) {
279  
-		stops += 1;
280  
-		i += 1;
281  
-	}
  269
+		// Create radial gradient if chosen
  270
+		if (params.r1 !== NULL || params.r2 !== NULL) {
  271
+			gradient = ctx.createRadialGradient(params.x1, params.y1, params.r1, params.x2, params.y2, params.r2);
  272
+		} else {
  273
+			gradient = ctx.createLinearGradient(params.x1, params.y1, params.x2, params.y2);
  274
+		}
282 275
 		
283  
-	// Calculate color stop percentages if absent
284  
-	for (i=1; i<=stops; i+=1) {
285  
-		percent = round(100 / (stops-1) * (i-1)) / 100;
286  
-		if (params['s' + i] === UNDEFINED) {
287  
-			params['s' + i] = percent;
  276
+		// Count number of color stops
  277
+		while (params['c' + i] !== UNDEFINED) {
  278
+			stops += 1;
  279
+			i += 1;
288 280
 		}
289  
-		gradient.addColorStop(params['s' + i], params['c' + i]);
  281
+		
  282
+		// Don't calculate gradient if only one color is defined
  283
+		if (stops === 1) {
  284
+			gradient = params['c1'];
  285
+		} else {
  286
+			
  287
+			// Constrain gradient to last color stop
  288
+			last = params['s' + stops];
  289
+			if (last !== UNDEFINED) {
  290
+				end = last * 100;
  291
+			}
  292
+				
  293
+			// Calculate color stop percentages if absent
  294
+			for (i=1; i<=stops; i+=1) {
  295
+				if (params['s' + i] === UNDEFINED) {
  296
+					params['s' + i] = (start + ((end - start) / (stops - 1)) * (i - 1)) / 100;
  297
+				} else {
  298
+					start = params['s' + i] * 100;
  299
+				}
  300
+				gradient.addColorStop(params['s' + i], params['c' + i]);
  301
+			}
  302
+		}		
  303
+	} else {
  304
+		gradient = NULL;
290 305
 	}
291 306
 	return gradient;
292 307
 };
@@ -296,18 +311,7 @@ $.fn.pattern = function(args) {
296 311
 	var $elems = this,
297 312
 		ctx, params = merge(new Prefs(), args),
298 313
 		img, pattern;
299  
-	
300  
-	ctx = loadCanvas($elems[0]);
301  
-	if (!ctx) {return NULL;}
302  
-	img = new Image();
303 314
 
304  
-	// Use defined element, if not, a source URL
305  
-	if (params.source.src) {
306  
-		img = params.source;
307  
-	} else {
308  
-		img.src = params.source;
309  
-	}
310  
-	
311 315
 	// Create pattern when image can be loaded
312 316
 	function create() {
313 317
 		var complete = FALSE;
@@ -328,16 +332,31 @@ $.fn.pattern = function(args) {
328 332
 		create();
329 333
 		callback();
330 334
 	}
331  
-	// Draw when image is loaded (if load() callback function is defined)
332  
-	if (!img.complete && params.load) {
333  
-		img.onload = onload;
334  
-	} else {
335  
-		// Draw image if already loaded (and if load() callback is not defined)
336  
-		if (!create()) {
  335
+	
  336
+	ctx = loadCanvas($elems[0]);
  337
+	if (ctx) {
  338
+		img = new Image();
  339
+	
  340
+		// Use defined element, if not, a source URL
  341
+		if (params.source.src) {
  342
+			img = params.source;
  343
+		} else {
  344
+			img.src = params.source;
  345
+		}
  346
+		
  347
+		// Draw when image is loaded (if load() callback function is defined)
  348
+		if (!img.complete && params.load) {
337 349
 			img.onload = onload;
338 350
 		} else {
339  
-			callback();
  351
+			// Draw image if already loaded (and if load() callback is not defined)
  352
+			if (!create()) {
  353
+				img.onload = onload;
  354
+			} else {
  355
+				callback();
  356
+			}
340 357
 		}
  358
+	} else {
  359
+		pattern = NULL;
341 360
 	}
342 361
 	return pattern;
343 362
 };
@@ -349,15 +368,17 @@ $.fn.clearCanvas = function(args) {
349 368
 
350 369
 	for (e=0; e<$elems.length; e+=1) {
351 370
 		ctx = loadCanvas($elems[e]);
352  
-		if (!ctx) {continue;}
  371
+		if (ctx) {
353 372
 
354  
-		positionShape(ctx, params, params.width, params.height);
  373
+			positionShape(ctx, params, params.width, params.height);
  374
+			
  375
+			// Clear entire canvas
  376
+			if (!params.width && !params.height) {
  377
+				ctx.clearRect(0, 0, $elems[e].width, $elems[e].height);
  378
+			} else {
  379
+				ctx.clearRect(params.x-params.width/2, params.y-params.height/2, params.width, params.height);
  380
+			}
355 381
 		
356  
-		// Clear entire canvas
357  
-		if (!params.width && !params.height) {
358  
-			ctx.clearRect(0, 0, $elems[e].width, $elems[e].height);
359  
-		} else {
360  
-			ctx.clearRect(params.x-params.width/2, params.y-params.height/2, params.width, params.height);
361 382
 		}
362 383
 	}
363 384
 	return $elems;
@@ -370,9 +391,9 @@ $.fn.saveCanvas = function() {
370 391
 	
371 392
 	for (e=0; e<$elems.length; e+=1) {
372 393
 		ctx = loadCanvas($elems[e]);
373  
-		if (!ctx) {continue;}
374  
-		
375  
-		ctx.save();
  394
+		if (ctx) {
  395
+			ctx.save();
  396
+		}
376 397
 	}
377 398
 	return $elems;
378 399
 };
@@ -384,9 +405,9 @@ $.fn.restoreCanvas = function() {
384 405
 	
385 406
 	for (e=0; e<$elems.length; e+=1) {
386 407
 		ctx = loadCanvas($elems[e]);
387  
-		if (!ctx) {continue;}
388  
-		
389  
-		ctx.restore();
  408
+		if (ctx) {
  409
+			ctx.restore();
  410
+		}
390 411
 	}
391 412
 	return $elems;
392 413
 };
@@ -398,12 +419,12 @@ $.fn.scaleCanvas = function(args) {
398 419
 		
399 420
 	for (e=0; e<$elems.length; e+=1) {
400 421
 		ctx = loadCanvas($elems[e]);
401  
-		if (!ctx) {continue;}
402  
-		
403  
-		ctx.save();
404  
-		ctx.translate(params.x, params.y);
405  
-		ctx.scale(params.scaleX, params.scaleY);
406  
-		ctx.translate(-params.x, -params.y);
  422
+		if (ctx) {
  423
+			ctx.save();
  424
+			ctx.translate(params.x, params.y);
  425
+			ctx.scale(params.scaleX, params.scaleY);
  426
+			ctx.translate(-params.x, -params.y);
  427
+		}
407 428
 	}
408 429
 	return $elems;
409 430
 };
@@ -415,10 +436,10 @@ $.fn.translateCanvas = function(args) {
415 436
 
416 437
 	for (e=0; e<$elems.length; e+=1) {
417 438
 		ctx = loadCanvas($elems[e]);
418  
-		if (!ctx) {continue;}
419  
-		
420  
-		ctx.save();
421  
-		ctx.translate(params.x, params.y);
  439
+		if (ctx) {
  440
+			ctx.save();
  441
+			ctx.translate(params.x, params.y);
  442
+		}
422 443
 	}
423 444
 	return $elems;
424 445
 };
@@ -430,9 +451,9 @@ $.fn.rotateCanvas = function(args) {
430 451
 	
431 452
 	for (e=0; e<$elems.length; e+=1) {
432 453
 		ctx = loadCanvas($elems[e]);
433  
-		if (!ctx) {continue;}
434  
-		
435  
-		positionShape(ctx, params, 0, 0);
  454
+		if (ctx) {
  455
+			positionShape(ctx, params, 0, 0);
  456
+		}
436 457
 	}
437 458
 	return $elems;
438 459
 };
@@ -445,42 +466,44 @@ $.fn.drawRect = function(args) {
445 466
 
446 467
 	for (e=0; e<$elems.length; e+=1) {
447 468
 		ctx = loadCanvas($elems[e]);
448  
-		if (!ctx) {continue;}
  469
+		if (ctx) {
449 470
 		
450  
-		setGlobals(ctx, params);
451  
-		positionShape(ctx, params, params.width, params.height);
452  
-		
453  
-		ctx.beginPath();
454  
-		// Draw a rounded rectangle if chosen
455  
-		if (params.cornerRadius) {
456  
-			params.closed = TRUE;
457  
-			x1 = params.x - params.width/2;
458  
-			y1 = params.y - params.height/2;
459  
-			x2 = params.x + params.width/2;
460  
-			y2 = params.y + params.height/2;
461  
-			r = params.cornerRadius;
462  
-			// Prevent over-rounded corners
463  
-			if ((x2 - x1) - (2 * r) < 0) {
464  
-				r = (x2 - x1) / 2;
465  
-			}
466  
-			if ((y2 - y1) - (2 * r) < 0) {
467  
-				r = (y2 - y1) / 2;
  471
+			setGlobals(ctx, params);
  472
+			positionShape(ctx, params, params.width, params.height);
  473
+			
  474
+			ctx.beginPath();
  475
+			// Draw a rounded rectangle if chosen
  476
+			if (params.cornerRadius) {
  477
+				params.closed = TRUE;
  478
+				x1 = params.x - params.width/2;
  479
+				y1 = params.y - params.height/2;
  480
+				x2 = params.x + params.width/2;
  481
+				y2 = params.y + params.height/2;
  482
+				r = params.cornerRadius;
  483
+				// Prevent over-rounded corners
  484
+				if ((x2 - x1) - (2 * r) < 0) {
  485
+					r = (x2 - x1) / 2;
  486
+				}
  487
+				if ((y2 - y1) - (2 * r) < 0) {
  488
+					r = (y2 - y1) / 2;
  489
+				}
  490
+				ctx.moveTo(x1+r,y1);
  491
+				ctx.lineTo(x2-r,y1);
  492
+				ctx.arc(x2-r, y1+r, r, 3*PI/2, PI*2, FALSE);
  493
+				ctx.lineTo(x2,y2-r);
  494
+				ctx.arc(x2-r, y2-r, r, 0, PI/2, FALSE);
  495
+				ctx.lineTo(x1+r,y2);
  496
+				ctx.arc(x1+r, y2-r, r, PI/2, PI, FALSE);
  497
+				ctx.lineTo(x1,y1+r);
  498
+				ctx.arc(x1+r, y1+r, r, PI, 3*PI/2, FALSE);
  499
+			} else {
  500
+				ctx.rect(params.x-params.width/2, params.y-params.height/2, params.width, params.height);
468 501
 			}
469  
-			ctx.moveTo(x1+r,y1);
470  
-			ctx.lineTo(x2-r,y1);
471  
-			ctx.arc(x2-r, y1+r, r, 3*PI/2, PI*2, FALSE);
472  
-			ctx.lineTo(x2,y2-r);
473  
-			ctx.arc(x2-r, y2-r, r, 0, PI/2, FALSE);
474  
-			ctx.lineTo(x1+r,y2);
475  
-			ctx.arc(x1+r, y2-r, r, PI/2, PI, FALSE);
476  
-			ctx.lineTo(x1,y1+r);
477  
-			ctx.arc(x1+r, y1+r, r, PI, 3*PI/2, FALSE);
478  
-		} else {
479  
-			ctx.rect(params.x-params.width/2, params.y-params.height/2, params.width, params.height);
  502
+			ctx.restore();
  503
+			if (params.event) {checkEvents.call($elems[e], ctx, args);}
  504
+			closePath(ctx, params);
  505
+			
480 506
 		}
481  
-		ctx.restore();
482  
-		if (params.event) {checkEvents.call($elems[e], ctx, args);}
483  
-		closePath(ctx, params);
484 507
 	}
485 508
 	return $elems;
486 509
 };
@@ -497,18 +520,20 @@ $.fn.drawArc = function(args) {
497 520
 		
498 521
 	for (e=0; e<$elems.length; e+=1) {
499 522
 		ctx = loadCanvas($elems[e]);
500  
-		if (!ctx) {continue;}
  523
+		if (ctx) {
  524
+			
  525
+			setGlobals(ctx, params);
  526
+			positionShape(ctx, params, params.radius*2, params.radius*2);
  527
+	
  528
+			// Draw arc
  529
+			ctx.beginPath();
  530
+			ctx.arc(params.x, params.y, params.radius, (params.start*params.toRad)-(PI/2), (params.end*params.toRad)-(PI/2), params.ccw);
  531
+			// Close path if chosen
  532
+			ctx.restore();
  533
+			if (params.event) {checkEvents.call($elems[e], ctx, args);}
  534
+			closePath(ctx, params);
501 535
 		
502  
-		setGlobals(ctx, params);
503  
-		positionShape(ctx, params, params.radius*2, params.radius*2);
504  
-
505  
-		// Draw arc
506  
-		ctx.beginPath();
507  
-		ctx.arc(params.x, params.y, params.radius, (params.start*params.toRad)-(PI/2), (params.end*params.toRad)-(PI/2), params.ccw);
508  
-		// Close path if chosen
509  
-		ctx.restore();
510  
-		if (params.event) {checkEvents.call($elems[e], ctx, args);}
511  
-		closePath(ctx, params);
  536
+		}
512 537
 	}
513 538
 	return $elems;
514 539
 };
@@ -521,21 +546,23 @@ $.fn.drawEllipse = function(args) {
521 546
 		
522 547
 	for (e=0; e<$elems.length; e+=1) {
523 548
 		ctx = loadCanvas($elems[e]);
524  
-		if (!ctx) {continue;}
525  
-		
526  
-		setGlobals(ctx, params);
527  
-		positionShape(ctx, params, params.width, params.height);
  549
+		if (ctx) {
  550
+			
  551
+			setGlobals(ctx, params);
  552
+			positionShape(ctx, params, params.width, params.height);
  553
+			
  554
+			// Create ellipse
  555
+			ctx.beginPath();
  556
+			ctx.moveTo(params.x, params.y-params.height/2);
  557
+			// Left side
  558
+			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);
  559
+			// Right side
  560
+			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);
  561
+			ctx.restore();
  562
+			if (params.event) {checkEvents.call($elems[e], ctx, args);}
  563
+			closePath(ctx, params);
528 564
 		
529  
-		// Create ellipse
530  
-		ctx.beginPath();
531  
-		ctx.moveTo(params.x, params.y-params.height/2);
532  
-		// Left side
533  
-		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);
534  
-		// Right side
535  
-		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);
536  
-		ctx.restore();
537  
-		if (params.event) {checkEvents.call($elems[e], ctx, args);}
538  
-		closePath(ctx, params);
  565
+		}
539 566
 	}
540 567
 	return $elems;
541 568
 };
@@ -548,26 +575,28 @@ $.fn.drawLine = function(args) {
548 575
 
549 576
 	for (e=0; e<$elems.length; e+=1) {
550 577
 		ctx = loadCanvas($elems[e]);
551  
-		if (!ctx) {continue;}
552  
-		
553  
-		setGlobals(ctx, params);
554  
-		
555  
-		// Draw each point
556  
-		ctx.beginPath();
557  
-		ctx.moveTo(params.x1, params.y1);
558  
-		while (TRUE) {
559  
-			lx = params['x' + l];
560  
-			ly = params['y' + l];
561  
-			if (lx !== UNDEFINED && ly !== UNDEFINED) {
562  
-				ctx.lineTo(lx, ly);
563  
-				l += 1;
564  
-			} else {
565  
-				break;
  578
+		if (ctx) {
  579
+			
  580
+			setGlobals(ctx, params);
  581
+			
  582
+			// Draw each point
  583
+			ctx.beginPath();
  584
+			ctx.moveTo(params.x1, params.y1);
  585
+			while (TRUE) {
  586
+				lx = params['x' + l];
  587
+				ly = params['y' + l];
  588
+				if (lx !== UNDEFINED && ly !== UNDEFINED) {
  589
+					ctx.lineTo(lx, ly);
  590
+					l += 1;
  591
+				} else {
  592
+					break;
  593
+				}
566 594
 			}
  595
+			if (params.event) {checkEvents.call($elems[e], ctx, args);}
  596
+			// Close path if chosen
  597
+			closePath(ctx, params);
  598
+		
567 599
 		}
568  
-		if (params.event) {checkEvents.call($elems[e], ctx, args);}
569  
-		// Close path if chosen
570  
-		closePath(ctx, params);
571 600
 	}
572 601
 	return $elems;
573 602
 };
@@ -580,28 +609,30 @@ $.fn.drawQuad = function(args) {
580 609
 
581 610
 	for (e=0; e<$elems.length; e+=1) {
582 611
 		ctx = loadCanvas($elems[e]);
583  
-		if (!ctx) {continue;}
  612
+		if (ctx) {
584 613
 		
585  
-		setGlobals(ctx, params);
586  
-			
587  
-		// Draw each point
588  
-		ctx.beginPath();
589  
-		ctx.moveTo(params.x1, params.y1);
590  
-		while (TRUE) {
591  
-			lx = params['x' + l];
592  
-			ly = params['y' + l];
593  
-			lcx = params['cx' + (l-1)];
594  
-			lcy = params['cy' + (l-1)];
595  
-			if (lx !== UNDEFINED && ly !== UNDEFINED && lcx !== UNDEFINED && lcy !== UNDEFINED) {
596  
-				ctx.quadraticCurveTo(lcx, lcy, lx, ly);
597  
-				l += 1;
598  
-			} else {
599  
-				break;
  614
+			setGlobals(ctx, params);
  615
+				
  616
+			// Draw each point
  617
+			ctx.beginPath();
  618
+			ctx.moveTo(params.x1, params.y1);
  619
+			while (TRUE) {
  620
+				lx = params['x' + l];
  621
+				ly = params['y' + l];
  622
+				lcx = params['cx' + (l-1)];
  623
+				lcy = params['cy' + (l-1)];
  624
+				if (lx !== UNDEFINED && ly !== UNDEFINED && lcx !== UNDEFINED && lcy !== UNDEFINED) {
  625
+					ctx.quadraticCurveTo(lcx, lcy, lx, ly);
  626
+					l += 1;
  627
+				} else {
  628
+					break;
  629
+				}
600 630
 			}
  631
+			if (params.event) {checkEvents.call($elems[e], ctx, args);}
  632
+			// Close path if chosen
  633
+			closePath(ctx, params);
  634
+		
601 635
 		}
602  
-		if (params.event) {checkEvents.call($elems[e], ctx, args);}
603  
-		// Close path if chosen
604  
-		closePath(ctx, params);
605 636
 	}
606 637
 	return $elems;
607 638
 };
@@ -617,31 +648,33 @@ $.fn.drawBezier = function(args) {
617 648
 
618 649
 	for (e=0; e<$elems.length; e+=1) {
619 650
 		ctx = loadCanvas($elems[e]);
620  
-		if (!ctx) {continue;}
  651
+		if (ctx) {
621 652
 		
622  
-		setGlobals(ctx, params);
623  
-	
624  
-		// Draw each point
625  
-		ctx.beginPath();
626  
-		ctx.moveTo(params.x1, params.y1);
627  
-		while (TRUE) {
628  
-			lx = params['x' + l];
629  
-			ly = params['y' + l];
630  
-			lcx1 = params['cx' + lc];
631  
-			lcy1 = params['cy' + lc];
632  
-			lcx2 = params['cx' + (lc+1)];
633  
-			lcy2 = params['cy' + (lc+1)];
634  
-			if (lx !== UNDEFINED && ly !== UNDEFINED && lcx1 !== UNDEFINED && lcy1 !== UNDEFINED && lcx2 !== UNDEFINED && lcy2 !== UNDEFINED) {
635  
-				ctx.bezierCurveTo(lcx1, lcy1, lcx2, lcy2, lx, ly);
636  
-				l += 1;
637  
-				lc += 2;
638  
-			} else {
639  
-				break;
  653
+			setGlobals(ctx, params);
  654
+		
  655
+			// Draw each point
  656
+			ctx.beginPath();
  657
+			ctx.moveTo(params.x1, params.y1);
  658
+			while (TRUE) {
  659
+				lx = params['x' + l];
  660
+				ly = params['y' + l];
  661
+				lcx1 = params['cx' + lc];
  662
+				lcy1 = params['cy' + lc];
  663
+				lcx2 = params['cx' + (lc+1)];
  664
+				lcy2 = params['cy' + (lc+1)];
  665
+				if (lx !== UNDEFINED && ly !== UNDEFINED && lcx1 !== UNDEFINED && lcy1 !== UNDEFINED && lcx2 !== UNDEFINED && lcy2 !== UNDEFINED) {
  666
+					ctx.bezierCurveTo(lcx1, lcy1, lcx2, lcy2, lx, ly);
  667
+					l += 1;
  668
+					lc += 2;
  669
+				} else {
  670
+					break;
  671
+				}
640 672
 			}
  673
+			if (params.event) {checkEvents.call($elems[e], ctx, args);}
  674
+			// Close path if chosen
  675
+			closePath(ctx, params);
  676
+		
641 677
 		}
642  
-		if (params.event) {checkEvents.call($elems[e], ctx, args);}
643  
-		// Close path if chosen
644  
-		closePath(ctx, params);
645 678
 	}
646 679
 	return $elems;
647 680
 };
@@ -653,17 +686,19 @@ $.fn.drawText = function(args) {
653 686
 
654 687
 	for (e=0; e<$elems.length; e+=1) {
655 688
 		ctx = loadCanvas($elems[e]);
656  
-		if (!ctx) {continue;}
  689
+		if (ctx) {
  690
+			
  691
+			setGlobals(ctx, params);
657 692
 		
658  
-		setGlobals(ctx, params);
659  
-	
660  
-		// Set text-specific properties
661  
-		ctx.textBaseline = params.baseline;
662  
-		ctx.textAlign = params.align;
663  
-		ctx.font = params.font;
  693
+			// Set text-specific properties
  694
+			ctx.textBaseline = params.baseline;
  695
+			ctx.textAlign = params.align;
  696
+			ctx.font = params.font;
  697
+			
  698
+			ctx.strokeText(params.text, params.x, params.y);
  699
+			ctx.fillText(params.text, params.x, params.y);
664 700
 		
665  
-		ctx.strokeText(params.text, params.x, params.y);
666  
-		ctx.fillText(params.text, params.x, params.y);
  701
+		}
667 702
 	}
668 703
 	return $elems;
669 704
 };
@@ -800,26 +835,28 @@ $.fn.drawImage = function(args) {
800 835
 	for (e=0; e<$elems.length; e+=1) {
801 836
 		elem = $elems[e];
802 837
 		ctx = loadCanvas($elems[e]);
803  
-		if (!ctx) {continue;}
  838
+		if (ctx) {
804 839
 		
805  
-		setGlobals(ctx, params);
806  
-		
807  
-		// Draw when image is loaded (if chosen)
808  
-		if (!img.complete && params.load) {
809  
-			img.onload = onload;
810  
-		} else {
811  
-			// Draw image if loaded
812  
-			if (!draw(ctx)) {
  840
+			setGlobals(ctx, params);
  841
+			
  842
+			// Draw when image is loaded (if chosen)
  843
+			if (!img.complete && params.load) {
813 844
 				img.onload = onload;
814 845
 			} else {
815  
-				callback();
  846
+				// Draw image if loaded
  847
+				if (!draw(ctx)) {
  848
+					img.onload = onload;
  849
+				} else {
  850
+					callback();
  851
+				}
816 852
 			}
  853
+		
817 854
 		}
818 855
 	}
819 856
 	return $elems;
820 857
 };
821 858
 
822  
-// Draw polygon
  859
+// Draw equiangular (regular) polygon
823 860
 $.fn.drawPolygon = function(args) {
824 861
 	var $elems = this, ctx, e,
825 862
 		params = merge(new Prefs(), args),
@@ -831,36 +868,38 @@ $.fn.drawPolygon = function(args) {
831 868
 	params.closed = TRUE;
832 869
 	
833 870
 	if (params.sides > 2) {
834  
-	for (e=0; e<$elems.length; e+=1) {
835  
-		ctx = loadCanvas($elems[e]);
836  
-		if (!ctx) {continue;}
837  
-		
838  
-		setGlobals(ctx, params);
839  
-		
840  
-		// Calculate points and draw
841  
-		positionShape(ctx, params, params.radius, params.radius);
842  
-		ctx.beginPath();
843  
-		for (i=0; i<params.sides; i+=1) {
844  
-			x1 = params.x + round(params.radius * cos(theta));
845  
-			y1 = params.y + round(params.radius * sin(theta));
846  
-			// Draw path
847  
-			if (i === 0) {
848  
-				ctx.moveTo(x1, y1);
849  
-			} else {
850  
-				ctx.lineTo(x1, y1);
851  
-			}
852  
-			// Project sides if chosen
853  
-			if (params.projection) {
854  
-				x2 = params.x + round((apothem+apothem*params.projection) * cos(theta+inner));
855  
-				y2 = params.y + round((apothem+apothem*params.projection) * sin(theta+inner));
856  
-				ctx.lineTo(x2, y2);
  871
+		for (e=0; e<$elems.length; e+=1) {
  872
+			ctx = loadCanvas($elems[e]);
  873
+			if (ctx) {
  874
+			
  875
+				setGlobals(ctx, params);
  876
+				
  877
+				// Calculate points and draw
  878
+				positionShape(ctx, params, params.radius, params.radius);
  879
+				ctx.beginPath();
  880
+				for (i=0; i<params.sides; i+=1) {
  881
+					x1 = params.x + round(params.radius * cos(theta));
  882
+					y1 = params.y + round(params.radius * sin(theta));
  883
+					// Draw path
  884
+					if (i === 0) {
  885
+						ctx.moveTo(x1, y1);
  886
+					} else {
  887
+						ctx.lineTo(x1, y1);
  888
+					}
  889
+					// Project sides if chosen
  890
+					if (params.projection) {
  891
+						x2 = params.x + round((apothem+apothem*params.projection) * cos(theta+inner));
  892
+						y2 = params.y + round((apothem+apothem*params.projection) * sin(theta+inner));
  893
+						ctx.lineTo(x2, y2);
  894
+					}
  895
+					theta += dtheta;
  896
+				}
  897
+				ctx.restore();
  898
+				if (params.event) {checkEvents.call($elems[e], ctx, args);}
  899
+				closePath(ctx, params);
  900
+				
857 901
 			}
858  
-			theta += dtheta;
859 902
 		}
860  
-		ctx.restore();
861  
-		if (params.event) {checkEvents.call($elems[e], ctx, args);}
862  
-		closePath(ctx, params);
863  
-	}
864 903
 	}
865 904
 	return $elems;
866 905
 };
@@ -875,7 +914,7 @@ $.fn.setPixels = function(args) {
875 914
 	for (e=0; e<$elems.length; e+=1) {
876 915
 			elem = $elems[e];
877 916
 			ctx = loadCanvas($elems[e]);
878  
-		if (!ctx) {continue;}
  917
+		if (ctx) {
879 918
 		
880 919
 			// Measure (x, y) from center of region
881 920
 			if (!params.x && !params.y && !params.width && !params.height) {
@@ -908,6 +947,8 @@ $.fn.setPixels = function(args) {
908 947
 			// Put pixels on canvas
909 948
 			ctx.putImageData(imgData, params.x-params.width/2, params.y-params.height/2);
910 949
 			ctx.restore();
  950
+		
  951
+		}
911 952
 	}
912 953
 	return $elems;
913 954
 };
@@ -1006,7 +1047,9 @@ function toRgba(color) {
1006 1047
 function getFrame(fx, i) {
1007 1048
 	fx.now[i] = fx.start[i] + (fx.end[i] - fx.start[i]) * fx.pos;
1008 1049
 	// Don't round a color's alpha value
1009  
-	if (i < 3) {fx.now[i] = round(fx.now[i]);}
  1050
+	if (i < 3) {
  1051
+		fx.now[i] = round(fx.now[i]);
  1052
+	}
1010 1053
 }
1011 1054
 
1012 1055
 // Animate a hex or RGB color
@@ -1043,11 +1086,11 @@ function supportColorProps(props) {
1043 1086
 $.fn.getLayers = function() {
1044 1087
 	var elem = this[0], layers;
1045 1088
 	if (!elem || !elem.getContext) {return NULL;}
1046  
-	layers = $.data(elem, 'layers');
  1089
+	layers = $.data(elem, 'jCanvas-layers');
1047 1090
 	// Create layers array if none exists
1048 1091
 	if (!layers) {
1049 1092
 		layers = [];
1050  
-		$.data(elem, 'layers', layers);
  1093
+		$.data(elem, 'jCanvas-layers', layers);
1051 1094
 	}
1052 1095
 	return layers;
1053 1096
 };
@@ -1080,20 +1123,28 @@ $.fn.addLayer = function(args) {
1080 1123
 
1081 1124
 	for (e=0; e<$elems.length; e+=1) {
1082 1125
 		$elem = $($elems[e]);
1083  
-		if (!loadCanvas($elems[e])) {continue;}
  1126
+		if (loadCanvas($elems[e])) {
1084 1127
 		
1085  
-		layers = $elem.getLayers();
1086  
-		// If layer is a function
1087  
-		if (typeof params === 'function') {
1088  
-			params.method = 'draw';
1089  
-		}
1090  
-		layers.push(params);
1091  
-		// Check for any jCanvas events and enable them
1092  
-		for (event in jCanvas.events) {
1093  
-			if (jCanvas.events.hasOwnProperty(event) && params[event]) {
1094  
-				jCanvas.events[event].call(window, $elem, params, layers.length-1);
1095  
-				params.event = TRUE;
  1128
+			layers = $elem.getLayers();
  1129
+			// If layer is a function
  1130
+			if (typeof params === 'function') {
  1131
+				params.method = 'draw';
  1132
+			} else {
  1133
+				// Ensure width/height of shapes (other than images) can be animated without specifying those properties
  1134
+				if (params.method !== 'drawImage') {
  1135
+					params.width = params.width || 0;
  1136
+					params.height = params.width || 0;
  1137
+				}
  1138
+				// Check for any associated jCanvas events and enable them
  1139
+				for (event in jCanvas.events) {
  1140
+					if (jCanvas.events.hasOwnProperty(event) && params[event]) {
  1141
+						jCanvas.events[event].call(window, $elem, params, layers.length-1);
  1142
+						params.event = TRUE;
  1143
+					}
  1144
+				}
1096 1145
 			}
  1146
+			layers.push(params);
  1147
+		
1097 1148
 		}
1098 1149
 	}
1099 1150
 	$elems.drawLayers();
@@ -1103,60 +1154,65 @@ $.fn.addLayer = function(args) {
1103 1154
 
1104 1155
 // Remove all jCanvas layers
1105 1156
 $.fn.removeLayers = function() {
1106  
-	(this.getLayers() || []).length = 0;
1107  
-	return this;
1108  
-};
1109  
-
1110  
-// Remove a jCanvas layer
1111  
-$.fn.removeLayer = function(index) {
1112  
-	index = index || 0;
1113  
-	(this.getLayers() || []).splice(index, 1);
  1157
+	var $elems = this, layers, e;
  1158
+	for (e=0; e<$elems.length; e+=1) {
  1159
+		layers = $($elems[e]).getLayers() || [];
  1160
+		layers.length = 0;
  1161
+	}
1114 1162
 	return this;
1115 1163
 };
1116 1164
 
1117  
-// Get a single jCanvas layer
  1165
+// Remove a single jCanvas layer
1118 1166
 $.fn.removeLayer = function(index) {
1119  
-	var type = typeof index,
1120  
-		layers = (this.getLayers() || []), i;
1121  
-	if (type === 'string') {
1122  
-		for (i=0; i<layers.length; i+=1) {
1123  
-			if (layers[i].name === index) {
1124  
-				layers.splice(i, 1);
1125  
-				break;
  1167
+	var $elems = this, e,
  1168
+		type = typeof index,
  1169
+		layers, i;
  1170
+	for (e=0; e<$elems.length; e+=1) {
  1171
+		layers = $($elems[e]).getLayers() || [];
  1172
+		if (type === 'string') {
  1173
+			for (i=0; i<layers.length; i+=1) {
  1174
+				if (layers[i].name === index) {
  1175
+					layers.splice(i, 1);
  1176
+					break;
  1177
+				}
1126 1178
 			}
  1179
+		} else if (type === 'number') {
  1180
+			layers.splice(index, 1);
1127 1181
 		}
1128  
-	} else if (type === 'number') {
1129  
-		layers.splice(index, 1);
1130 1182
 	}
1131 1183
 	return this;
1132 1184
 };
1133 1185
 
1134 1186
 // Draw jCanvas layers
1135 1187
 $.fn.drawLayers = function() {
1136  
-	var $elems = this,
1137  
-		$elem,
1138  
-		ctx, params, layers, e, i;
  1188
+	var $elems = this, $elem, ctx,
  1189
+		params, layers, e, i;
1139 1190
 	
1140 1191
 	for (e=0; e<$elems.length; e+=1) {
1141 1192
 		$elem = $($elems[e]);
1142 1193
 		ctx = loadCanvas($elem[0]);
1143  
-		if (!ctx) {continue;}
  1194
+		if (ctx) {
1144 1195
 		
1145  
-		layers = $elem.getLayers();
1146  
-		// Clear canvas first
1147  
-		ctx.clearRect(0, 0, $elem[0].width, $elem[0].height);
1148  
-		// Draw items on queue
1149  
-		for (i=0; i<layers.length; i+=1) {
1150  
-			params = layers[i];
1151  
-			// If layer is a function
1152  
-			if (params.method === 'draw') {
1153  
-				params.call($elem[0], ctx);
1154  
-			// If layer is an object
1155  
-			} else {
1156  
-				if ($.fn[params.method]) {
1157  
-					$.fn[params.method].call($elem, params);
  1196
+			layers = $elem.getLayers();
  1197
+			// Clear canvas first
  1198
+			ctx.clearRect(0, 0, $elem[0].width, $elem[0].height);
  1199
+			// Draw items on queue
  1200
+			for (i=0; i<layers.length; i+=1) {
  1201
+				params = layers[i];
  1202
+				// Only draw if layer is visible
  1203
+				if (params.visible) {
  1204
+					// If layer is a function
  1205
+					if (params.method === 'draw') {
  1206
+						params.call($elem[0], ctx);
  1207
+					// If layer is an object
  1208
+					} else {
  1209
+						if ($.fn[params.method]) {
  1210
+							$.fn[params.method].call($elem, params);
  1211
+						}
  1212
+					}
1158 1213
 				}
1159 1214
 			}
  1215
+		
1160 1216
 		}
1161 1217
 	}
1162 1218
 	return $elems;
@@ -1164,9 +1220,9 @@ $.fn.drawLayers = function() {
1164 1220
 
1165 1221
 // Animate jCanvas layer
1166 1222
 $.fn.animateLayer = function() {
1167  
-	var $elems = this,
  1223
+	var $elems = this, $elem,
1168 1224
 		args = ([]).slice.call(arguments, 0),
1169  
-		$elem, layer, e;
  1225
+		layer, e;
1170 1226
 		
1171 1227
 	// Deal with all cases of argument placement
1172 1228
 	
@@ -1206,7 +1262,7 @@ $.fn.animateLayer = function() {
1206 1262
 		};
1207 1263
 	}
1208 1264
 	function step($elem, layer) {
1209  
-		return function(fx) {
  1265
+		return function() {
1210 1266
 			showProps(cssProps, layer);
1211 1267
 			$elem.drawLayers();
1212 1268
 		};
@@ -1214,30 +1270,31 @@ $.fn.animateLayer = function() {
1214 1270
 
1215 1271
 	for (e=0; e<$elems.length; e+=1) {
1216 1272
 		$elem = $($elems[e]);
1217  
-		// If a layer object was passed, use it as a reference
1218  
-		if (args[0].layer) {
1219  
-			layer = args[0];
1220  
-		} else {
1221  
-			layer = $elem.getLayer(args[0]);
1222  
-		}
1223  
-		// Ignore layers that are functions
1224  
-		if (!layer || layer.method === 'draw') {
1225  
-			continue;
  1273
+		if (loadCanvas($elems[e])) {
  1274
+			// If a layer object was passed, use it as a reference
  1275
+			if (args[0].layer) {
  1276
+				layer = args[0];
  1277
+			} else {
  1278
+				layer = $elem.getLayer(args[0]);
  1279
+			}
  1280
+			// Ignore layers that are functions
  1281
+			if (layer && layer.method !== 'draw') {
  1282
+	
  1283
+				// Allow jQuery to animate jCanvas CSS-named properties (width, opacity, etc.)
  1284
+				hideProps(cssProps, layer);
  1285
+				hideProps(cssProps, args[1]);
  1286
+				// Animate layer
  1287
+				$(layer).animate(args[1], {
  1288
+					duration: args[2],
  1289
+					easing: ($.easing[args[3]] ? args[3] : NULL),
  1290
+					// When animation completes
  1291
+					complete: complete($elem, layer),
  1292
+					// Redraw canvas for every animation frame
  1293
+					step: step($elem, layer)
  1294
+				});
  1295
+				
  1296
+			}
1226 1297
 		}
1227  
-		// Merge properties so any property can be animated
1228  
-		layer = merge(layer, prefs, $.extend({}, layer));
1229  
-		// Allow jQuery to animate jCanvas CSS-named properties (width, opacity, etc.)
1230  
-		hideProps(cssProps, layer);
1231  
-		hideProps(cssProps, args[1]);
1232  
-		// Animate layer
1233  
-		$(layer).animate(args[1], {
1234  
-			duration: args[2],
1235  
-			easing: ($.easing[args[3]] ? args[3] : NULL),
1236  
-			// When animation completes
1237  
-			complete: complete($elem, layer),
1238  
-			// Redraw canvas for every animation frame
1239  
-			step: step($elem, layer)
1240  
-		});
1241 1298
 	}
1242 1299
 	return $elems;
1243 1300
 };
@@ -1257,12 +1314,12 @@ $.event.fix = function(event) {
1257 1314
 	return event;
1258 1315
 };
1259 1316
 
1260  
-// Enable canvas feature detection with $.support
1261  
-$.support.canvas = (document.createElement('canvas').getContext !== UNDEFINED);
1262  
-
1263 1317
 // Enable animation for color properties
1264 1318
 supportColorProps(colorProps);
1265 1319
 
  1320
+// Enable canvas feature detection with $.support
  1321
+$.support.canvas = (document.createElement('canvas').getContext !== UNDEFINED);
  1322
+
1266 1323
 // Export jCanvas functions
1267 1324
 jCanvas.defaults = defaults;
1268 1325
 jCanvas.prefs = prefs;
2  jcanvas.min.js
@@ -3,4 +3,4 @@ jCanvas v5.2b
3 3
 Copyright 2012, Caleb Evans
4 4
 Licensed under the MIT license
5 5
 */
6  
-(function(v,D,e,s,F,r,o,t,J,u,w){var x,L,C=v.extend,H=s.round,f=s.PI,p=s.sin,d=s.cos,l=v.event.fix,a={},z,A;function B(){}function I(M){if(!M){L=B.prototype=C({},x)}else{C(L,M)}return this}I.version="5.2b";I.events={};v.fn.jCanvas=I;x={align:"center",angle:0,baseline:"middle",ccw:J,closed:J,compositing:"source-over",cornerRadius:0,cropFromCenter:t,each:u,end:360,fillStyle:"transparent",font:"12pt sans-serif",fromCenter:t,height:null,inDegrees:t,load:u,mask:J,opacity:1,projection:0,r1:u,r2:u,radius:0,repeat:"repeat",rounded:J,scaleX:1,scaleY:1,shadowBlur:3,shadowColor:"transparent",shadowX:0,shadowY:0,sHeight:0,sides:3,source:"",start:0,strokeCap:"butt",strokeJoin:"miter",strokeStyle:"transparent",strokeWidth:1,sWidth:0,sx:u,sy:u,text:"",width:null,x:0,x1:0,x2:0,y:0,y1:0,y2:0};I();function c(M,N){M.fillStyle=N.fillStyle;M.strokeStyle=N.strokeStyle;M.lineWidth=N.strokeWidth;if(N.rounded){M.lineCap="round";M.lineJoin="round"}else{M.lineCap=N.strokeCap;M.lineJoin=N.strokeJoin}M.shadowOffsetX=N.shadowX;M.shadowOffsetY=N.shadowY;M.shadowBlur=N.shadowBlur;M.shadowColor=N.shadowColor;M.globalAlpha=N.opacity;M.globalCompositeOperation=N.compositing}function y(M){I.events[M]=function(N){N.unbind(M+".jCanvas").bind(M+".jCanvas",function(O){a.x=O.offsetX;a.y=O.offsetY;a.type=O.type;N.drawLayers()})}}y("click");y("dblclick");y("mousedown");y("mouseup");y("mousemove");function G(M,N){var O=N[a.type];if(a.type&&O&&M.isPointInPath(a.x,a.y)){N.mouseX=a.x;N.mouseY=a.y;a.x=w;a.y=w;O.call(this,N);c(M,N)}}function j(M){return(M.getContext?M.getContext("2d"):u)}function q(M,N){if(N.mask){M.save();M.clip()}if(N.closed){M.closePath();M.fill();M.stroke()}else{M.fill();M.stroke();M.closePath()}}function b(M){return(M.inDegrees?f/180:1)}function h(N,P,O,M){P.toRad=b(P);N.save();if(!P.fromCenter){P.x+=O/2;P.y+=M/2}if(P.angle){N.translate(P.x,P.y);N.rotate(P.angle*P.toRad);N.translate(-P.x,-P.y)}}function n(M){M=M||{};x=C(x,M.props);I();if(M.name){v.fn[M.name]=function(O){var S=this,P,N,Q,R=C(new B(),O);for(Q=0;Q<S.length;Q+=1){P=S[Q];N=j(P);if(!N){continue}c(N,R);R.toRad=b(R);M.fn.call(P,N,R)}return S}}return v.fn[M.name]}v.fn.loadCanvas=function(){return j(this[0])};v.fn.getCanvasImage=function(M){var N=this[0];if(!N||!N.toDataURL){return u}if(M===w){M="image/png"}else{M=M.replace(/^([a-z]+)$/gi,"image/$1").replace(/jpg/gi,"jpeg")}return N.toDataURL(M)};v.fn.draw=function(P){var O=this,M,N;for(N=0;N<O.length;N+=1){M=j(O[N]);if(!M){continue}P.call(O[N],M)}return O};v.fn.gradient=function(N){var T=this,M,S=C(new B(),N),R,Q,P=0,O=1;M=j(T[0]);if(!M){return u}if(S.r1!==u||S.r2!==u){R=M.createRadialGradient(S.x1,S.y1,S.r1,S.x2,S.y2,S.r2)}else{R=M.createLinearGradient(S.x1,S.y1,S.x2,S.y2)}while(S["c"+O]!==w){P+=1;O+=1}for(O=1;O<=P;O+=1){Q=H(100/(P-1)*(O-1))/100;if(S["s"+O]===w){S["s"+O]=Q}R.addColorStop(S["s"+O],S["c"+O])}return R};v.fn.pattern=function(S){var M=this,U,O=C(new B(),S),P,R;U=j(M[0]);if(!U){return u}P=new F();if(O.source.src){P=O.source}else{P.src=O.source}function Q(){var V=J;if(P.complete){R=U.createPattern(P,O.repeat);V=t}return V}function T(){if(O.load){O.load.call(M[0],R)}}function N(){Q();T()}if(!P.complete&&O.load){P.onload=N}else{if(!Q()){P.onload=N}else{T()}}return R};v.fn.clearCanvas=function(N){var Q=this,M,O,P=C(new B(),N);for(O=0;O<Q.length;O+=1){M=j(Q[O]);if(!M){continue}h(M,P,P.width,P.height);if(!P.width&&!P.height){M.clearRect(0,0,Q[O].width,Q[O].height)}else{M.clearRect(P.x-P.width/2,P.y-P.height/2,P.width,P.height)}}return Q};v.fn.saveCanvas=function(){var O=this,M,N;for(N=0;N<O.length;N+=1){M=j(O[N]);if(!M){continue}M.save()}return O};v.fn.restoreCanvas=function(){var O=this,M,N;for(N=0;N<O.length;N+=1){M=j(O[N]);if(!M){continue}M.restore()}return O};v.fn.scaleCanvas=function(N){var Q=this,M,O,P=C(new B(),N);for(O=0;O<Q.length;O+=1){M=j(Q[O]);if(!M){continue}M.save();M.translate(P.x,P.y);M.scale(P.scaleX,P.scaleY);M.translate(-P.x,-P.y)}return Q};v.fn.translateCanvas=function(N){var Q=this,M,O,P=C(new B(),N);for(O=0;O<Q.length;O+=1){M=j(Q[O]);if(!M){continue}M.save();M.translate(P.x,P.y)}return Q};v.fn.rotateCanvas=function(N){var Q=this,M,O,P=C(new B(),N);for(O=0;O<Q.length;O+=1){M=j(Q[O]);if(!M){continue}h(M,P,0,0)}return Q};v.fn.drawRect=function(S){var N=this,V,R,Q=C(new B(),S),P,U,O,T,M;for(R=0;R<N.length;R+=1){V=j(N[R]);if(!V){continue}c(V,Q);h(V,Q,Q.width,Q.height);V.beginPath();if(Q.cornerRadius){Q.closed=t;P=Q.x-Q.width/2;U=Q.y-Q.height/2;O=Q.x+Q.width/2;T=Q.y+Q.height/2;M=Q.cornerRadius;if((O-P)-(2*M)<0){M=(O-P)/2}if((T-U)-(2*M)<0){M=(T-U)/2}V.moveTo(P+M,U);V.lineTo(O-M,U);V.arc(O-M,U+M,M,3*f/2,f*2,J);V.lineTo(O,T-M);V.arc(O-M,T-M,M,0,f/2,J);V.lineTo(P+M,T);V.arc(P+M,T-M,M,f/2,f,J);V.lineTo(P,U+M);V.arc(P+M,U+M,M,f,3*f/2,J)}else{V.rect(Q.x-Q.width/2,Q.y-Q.height/2,Q.width,Q.height)}V.restore();if(Q.event){G.call(N[R],V,S)}q(V,Q)}return N};v.fn.drawArc=function(N){var Q=this,M,O,P=C(new B(),N);if(!P.inDegrees&&P.end===360){P.end=f*2}for(O=0;O<Q.length;O+=1){M=j(Q[O]);if(!M){continue}c(M,P);h(M,P,P.radius*2,P.radius*2);M.beginPath();M.arc(P.x,P.y,P.radius,(P.start*P.toRad)-(f/2),(P.end*P.toRad)-(f/2),P.ccw);M.restore();if(P.event){G.call(Q[O],M,N)}q(M,P)}return Q};v.fn.drawEllipse=function(N){var R=this,M,P,Q=C(new B(),N),O=Q.width*4/3;for(P=0;P<R.length;P+=1){M=j(R[P]);if(!M){continue}c(M,Q);h(M,Q,Q.width,Q.height);M.beginPath();M.moveTo(Q.x,Q.y-Q.height/2);M.bezierCurveTo(Q.x-O/2,Q.y-Q.height/2,Q.x-O/2,Q.y+Q.height/2,Q.x,Q.y+Q.height/2);M.bezierCurveTo(Q.x+O/2,Q.y+Q.height/2,Q.x+O/2,Q.y-Q.height/2,Q.x,Q.y-Q.height/2);M.restore();if(Q.event){G.call(R[P],M,N)}q(M,Q)}return R};v.fn.drawLine=function(O){var T=this,N,R,S=C(new B(),O),M=2,Q=0,P=0;for(R=0;R<T.length;R+=1){N=j(T[R]);if(!N){continue}c(N,S);N.beginPath();N.moveTo(S.x1,S.y1);while(t){Q=S["x"+M];P=S["y"+M];if(Q!==w&&P!==w){N.lineTo(Q,P);M+=1}else{break}}if(S.event){G.call(T[R],N,O)}q(N,S)}return T};v.fn.drawQuad=function(S){var M=this,V,R,Q=C(new B(),S),P=2,O=0,N=0,U=0,T=0;for(R=0;R<M.length;R+=1){V=j(M[R]);if(!V){continue}c(V,Q);V.beginPath();V.moveTo(Q.x1,Q.y1);while(t){O=Q["x"+P];N=Q["y"+P];U=Q["cx"+(P-1)];T=Q["cy"+(P-1)];if(O!==w&&N!==w&&U!==w&&T!==w){V.quadraticCurveTo(U,T,O,N);P+=1}else{break}}if(Q.event){G.call(M[R],V,S)}q(V,Q)}return M};v.fn.drawBezier=function(X){var M=this,Y,W,T=C(new B(),X),S=2,P=1,R=0,Q=0,V=0,O=0,U=0,N=0;for(W=0;W<M.length;W+=1){Y=j(M[W]);if(!Y){continue}c(Y,T);Y.beginPath();Y.moveTo(T.x1,T.y1);while(t){R=T["x"+S];Q=T["y"+S];V=T["cx"+P];O=T["cy"+P];U=T["cx"+(P+1)];N=T["cy"+(P+1)];if(R!==w&&Q!==w&&V!==w&&O!==w&&U!==w&&N!==w){Y.bezierCurveTo(V,O,U,N,R,Q);S+=1;P+=2}else{break}}if(T.event){G.call(M[W],Y,X)}q(Y,T)}return M};v.fn.drawText=function(N){var Q=this,M,O,P=C(new B(),N);for(O=0;O<Q.length;O+=1){M=j(Q[O]);if(!M){continue}c(M,P);M.textBaseline=P.baseline;M.textAlign=P.align;M.font=P.font;M.strokeText(P.text,P.x,P.y);M.fillText(P.text,P.x,P.y)}return Q};v.fn.drawImage=function(T){var M=this,W,O,S,Q=C(new B(),T),R,N;if(Q.source.src){R=Q.source}else{if(Q.source){R=new F();R.src=Q.source}}function U(X){if(R.complete===w||R.complete===t){N=R.width/R.height;Q.sWidth=Q.sWidth||R.width;Q.sHeight=Q.sHeight||R.height;if(Q.sWidth>R.width){Q.sWidth=R.width}if(Q.sHeight>R.height){Q.sHeight=R.height}if(Q.width===u&&Q.sWidth!==R.width){Q.width=Q.sWidth}if(Q.height===u&&Q.sHeight!==R.height){Q.height=Q.sHeight}if(Q.sx===u){if(Q.cropFromCenter){Q.sx=R.width/2}else{Q.sx=0}}if(Q.sy===u){if(Q.cropFromCenter){Q.sy=R.height/2}else{Q.sy=0}}if(!Q.cropFromCenter){Q.sx+=Q.sWidth/2;Q.sy+=Q.sHeight/2}if((Q.sx+Q.sWidth/2)>R.width){Q.sx=R.width-Q.sWidth/2}if((Q.sx-Q.sWidth/2)<0){Q.sx=Q.sWidth/2}if((Q.sy-Q.sHeight/2)<0){Q.sy=Q.sHeight/2}if((Q.sy+Q.sHeight/2)>R.height){Q.sy=R.height-Q.sHeight/2}if(Q.width!==u&&Q.height===u){T.height=Q.height=Q.width/N}else{if(Q.width===u&&Q.height!==u){T.width=Q.width=Q.height*N}else{if(Q.width===u&&Q.height===u){T.width=Q.width=R.width;T.height=Q.height=R.height}}}h(X,Q,Q.width,Q.height);X.drawImage(R,Q.sx-Q.sWidth/2,Q.sy-Q.sHeight/2,Q.sWidth,Q.sHeight,Q.x-Q.width/2,Q.y-Q.height/2,Q.width,Q.height);if(Q.event){X.fillStyle="#000";X.beginPath();X.rect(Q.x-Q.width/2,Q.y-Q.height/2,Q.width,Q.height);X.restore();G.call(M[S],X,T);X.closePath()}else{X.restore()}return t}}function V(){if(Q.load){Q.load.call(O)}}function P(){U(W);V()}for(S=0;S<M.length;S+=1){O=M[S];W=j(M[S]);if(!W){continue}c(W,Q);if(!R.complete&&Q.load){R.onload=P}else{if(!U(W)){R.onload=P}else{V()}}}return M};v.fn.drawPolygon=function(T){var M=this,Y,S,Q=C(new B(),T),Z=f/Q.sides,P=(f/2)+Z,X=(f*2)/Q.sides,W=d(X/2)*Q.radius,O,V,N,U,R;Q.closed=t;if(Q.sides>2){for(S=0;S<M.length;S+=1){Y=j(M[S]);if(!Y){continue}c(Y,Q);h(Y,Q,Q.radius,Q.radius);Y.beginPath();for(R=0;R<Q.sides;R+=1){O=Q.x+H(Q.radius*d(P));V=Q.y+H(Q.radius*p(P));if(R===0){Y.moveTo(O,V)}else{Y.lineTo(O,V)}if(Q.projection){N=Q.x+H((W+W*Q.projection)*d(P+Z));U=Q.y+H((W+W*Q.projection)*p(P+Z));Y.lineTo(N,U)}P+=X}Y.restore();if(Q.event){G.call(M[S],Y,T)}q(Y,Q)}}return M};v.fn.setPixels=function(U){var M=this,W,O,T,R,P=C(new B(),U),N,Q,S,V={};for(T=0;T<M.length;T+=1){O=M[T];W=j(M[T]);if(!W){continue}if(!P.x&&!P.y&&!P.width&&!P.height){P.width=O.width;P.height=O.height;P.x=P.width/2;P.y=P.height/2}h(W,P,P.width,P.height);N=W.getImageData(P.x-P.width/2,P.y-P.height/2,P.width,P.height);Q=N.data;S=Q.length;V=[];if(P.each!==u){for(R=0;R<S;R+=4){V.index=R/4;V.r=Q[R];V.g=Q[R+1];V.b=Q[R+2];V.a=Q[R+3];P.each.call(O,V);Q[R]=V.r;Q[R+1]=V.g;Q[R+2]=V.b;Q[R+3]=V.a}}W.putImageData(N,P.x-P.width/2,P.y-P.height/2);W.restore()}return M};function g(N,O){var M;for(M=0;M<N.length;M+=1){O[N[M]]=O["_"+N[M]]}}function i(N,O){var M;for(M=0;M<N.length;M+=1){O["_"+N[M]]=O[N[M]]}}z=["width","height","opacity"];A=["backgroundColor","color","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","fillStyle","strokeStyle","shadowColor"];function k(N){var P,Q,O=[],M=1;if(typeof N==="object"){O=N}else{if(N.match(/^[a-z]+$/gi)){if(N==="transparent"){N="rgba(255,255,255,0)"}Q=e.documentElement;P=Q.style.color;Q.style.color=N;N=v.css(Q,"color");Q.style.color=P}if(N.match(/^\#/gi)){if(N.length===4){N=N.replace(/([0-9a-f])/gi,"$1$1")}O=N.match(/[0-9a-f]{2}/gi);O[0]=o(O[0],16);O[1]=o(O[1],16);O[2]=o(O[2],16)}else{if(N.match(/^rgb/gi)){O=N.match(/[0-9\.]+/gi);if(N.match(/\%/gi)){M=2.55}O[0]=O[0]*M;O[1]=O[1]*M;O[2]=O[2]*M}}if(N.match("rgba")){O[3]=r(O[3])}else{O[3]=1}}return O}function K(N,M){N.now[M]=N.start[M]+(N.end[M]-N.start[M])*N.pos;if(M<3){N.now[M]=H(N.now[M])}}function E(M){if(typeof M.start!=="object"){M.start=k(M.start);M.end=k(M.end)}M.now=[];K(M,0);K(M,1);K(M,2);K(M,3);M.now="rgba("+M.now.join(",")+")";if(M.elem.style){M.elem.style[M.prop]=M.now}else{M.elem[M.prop]=M.now}}function m(M){var N;for(N=0;N<M.length;N+=1){if(!v.fx.step[M[N]]){v.fx.step[M[N]]=E}}}v.fn.getLayers=function(){var M=this[0],N;if(!M||!M.getContext){return u}N=v.data(M,"layers");if(!N){N=[];v.data(M,"layers",N)}return N};v.fn.getLayer=function(M){var P=this.getLayers(),O,N;if(!P){O=u}else{if(typeof M==="string"){for(N=0;N<P.length;N+=1){if(P[N].name===M){M=N;break}}}}M=M||0;O=P[M];return O};v.fn.addLayer=function(N){var S=this,M,R=C(N,new B(),v.extend({},N)),Q,O,P;R.layer=t;for(P=0;P<S.length;P+=1){M=v(S[P]);if(!j(S[P])){continue}Q=M.getLayers();if(typeof R==="function"){R.method="draw"}Q.push(R);for(O in I.events){if(I.events.hasOwnProperty(O)&&R[O]){I.events[O].call(D,M,R,Q.length-1);R.event=t}}}S.drawLayers();return S};v.fn.removeLayers=function(){(this.getLayers()||[]).length=0;return this};v.fn.removeLayer=function(M){M=M||0;(this.getLayers()||[]).splice(M,1);return this};v.fn.removeLayer=function(M){var O=typeof M,P=(this.getLayers()||[]),N;if(O==="string"){for(N=0;N<P.length;N+=1){if(P[N].name===M){P.splice(N,1);break}}}else{if(O==="number"){P.splice(M,1)}}return this};v.fn.drawLayers=function(){var S=this,N,M,R,Q,P,O;for(P=0;P<S.length;P+=1){N=v(S[P]);M=j(N[0]);if(!M){continue}Q=N.getLayers();M.clearRect(0,0,N[0].width,N[0].height);for(O=0;O<Q.length;O+=1){R=Q[O];if(R.method==="draw"){R.call(N[0],M)}else{if(v.fn[R.method]){v.fn[R.method].call(N,R)}}}}return S};v.fn.animateLayer=function(){var S=this,O=([]).slice.call(arguments,0),N,P,R;if(typeof O[0]==="object"&&!O[0].layer){O.unshift(0)}if(O[2]===w){O.splice(2,0,u);O.splice(3,0,u);O.splice(4,0,function(){})}else{if(typeof O[2]==="function"){O.splice(2,0,u);O.splice(3,0,u)}}if(O[3]===w){O[3]=u;O.splice(4,0,function(){})}else{if(typeof O[3]==="function"){O.splice(3,0,u)}}if(O[4]===w){O[4]=function(){}}function M(T,U){return function(){g(z,U);T.drawLayers();O[4].call(T[0])}}function Q(T,U){return function(V){g(z,U);T.drawLayers()}}for(R=0;R<S.length;R+=1){N=v(S[R]);if(O[0].layer){P=O[0]}else{P=N.getLayer(O[0])}if(!P||P.method==="draw"){continue}P=C(P,L,v.extend({},P));i(z,P);i(z,O[1]);v(P).animate(O[1],{duration:O[2],easing:(v.easing[O[3]]?O[3]:u),complete:M(N,P),step:Q(N,P)})}return S};v.event.fix=function(M){var N;M=l.call(v.event,M);if(M.pageX!==w&&M.offsetX===w){N=v(M.target).offset();if(N){M.offsetX=M.pageX-N.left;M.offsetY=M.pageY-N.top}}return M};v.support.canvas=(e.createElement("canvas").getContext!==w);m(A);I.defaults=x;I.prefs=L;I.extend=n;v.jCanvas=I}(jQuery,window,document,Math,Image,parseFloat,parseInt,true,false,null));
  6
+(function(u,C,c,r,E,q,m,s,I,t,v){var w,K,B=u.extend,G=r.round,d=r.PI,n=r.sin,b=r.cos,j=u.event.fix,p={},y,z;function A(){}function H(L){if(L){B(K,L)}else{K=A.prototype=B({},w)}return this}H.version="5.2b";H.events={};u.fn.jCanvas=H;w={align:"center",angle:0,baseline:"middle",ccw:I,closed:I,compositing:"source-over",cornerRadius:0,cropFromCenter:s,each:t,end:360,fillStyle:"transparent",font:"12pt sans-serif",fromCenter:s,height:t,inDegrees:s,load:t,mask:I,opacity:1,projection:0,r1:t,r2:t,radius:0,repeat:"repeat",rounded:I,scaleX:1,scaleY:1,shadowBlur:3,shadowColor:"transparent",shadowX:0,shadowY:0,sHeight:0,sides:3,source:"",start:0,strokeCap:"butt",strokeJoin:"miter",strokeStyle:"transparent",strokeWidth:1,sWidth:0,sx:t,sy:t,text:"",visible:s,width:t,x:0,x1:0,x2:0,y:0,y1:0,y2:0};H();function a(L,M){L.fillStyle=M.fillStyle;L.strokeStyle=M.strokeStyle;L.lineWidth=M.strokeWidth;if(M.rounded){L.lineCap="round";L.lineJoin="round"}else{L.lineCap=M.strokeCap;L.lineJoin=M.strokeJoin}L.shadowOffsetX=M.shadowX;L.shadowOffsetY=M.shadowY;L.shadowBlur=M.shadowBlur;L.shadowColor=M.shadowColor;L.globalAlpha=M.opacity;L.globalCompositeOperation=M.compositing}function x(L){H.events[L]=function(M){M.unbind(L+".jCanvas").bind(L+".jCanvas",function(N){p.x=N.offsetX;p.y=N.offsetY;p.type=N.type;M.drawLayers()})}}x("click");x("dblclick");x("mousedown");x("mouseup");x("mousemove");function F(L,M){var N=M[p.type];if(p.type&&N&&L.isPointInPath(p.x,p.y)){M.mouseX=p.x;M.mouseY=p.y;p.x=v;p.y=v;N.call(this,M);a(L,M)}}function h(L){return(L.getContext?L.getContext("2d"):t)}function o(L,M){if(M.mask){L.save();L.clip()}if(M.closed){L.closePath();L.fill();L.stroke()}else{L.fill();L.stroke();L.closePath()}}function f(M,O,N,L){O.toRad=(O.inDegrees?d/180:1);M.save();if(!O.fromCenter){O.x+=N/2;O.y+=L/2}if(O.angle){M.translate(O.x,O.y);M.rotate(O.angle*O.toRad);M.translate(-O.x,-O.y)}}function l(L){L=L||{};w=B(w,L.props);H();if(L.name){u.fn[L.name]=function(N){var R=this,O,M,P,Q=B(new A(),N);for(P=0;P<R.length;P+=1){O=R[P];M=h(O);if(M){a(M,Q);L.fn.call(O,M,Q)}}return R}}return u.fn[L.name]}u.fn.loadCanvas=function(){return h(this[0])};u.fn.getCanvasImage=function(L){var M=this[0];if(!M||!M.toDataURL){return t}if(L===v){L="image/png"}else{L=L.replace(/^([a-z]+)$/gi,"image/$1").replace(/jpg/gi,"jpeg")}return M.toDataURL(L)};u.fn.draw=function(O){var N=this,L,M;for(M=0;M<N.length;M+=1){L=h(N[M]);if(L){O.call(N[M],L)}}return N};u.fn.gradient=function(Q){var L=this,U,N=B(new A(),Q),R,T=0,M=0,O=100,P=1,S;U=h(L[0]);if(U){if(N.r1!==t||N.r2!==t){R=U.createRadialGradient(N.x1,N.y1,N.r1,N.x2,N.y2,N.r2)}else{R=U.createLinearGradient(N.x1,N.y1,N.x2,N.y2)}while(N["c"+P]!==v){T+=1;P+=1}if(T===1){R=N.c1}else{S=N["s"+T];if(S!==v){O=S*100}for(P=1;P<=T;P+=1){if(N["s"+P]===v){N["s"+P]=(M+((O-M)/(T-1))*(P-1))/100}else{M=N["s"+P]*100}R.addColorStop(N["s"+P],N["c"+P])}}}else{R=t}return R};u.fn.pattern=function(R){var L=this,T,N=B(new A(),R),O,Q;function P(){var U=I;if(O.complete){Q=T.createPattern(O,N.repeat);U=s}return U}function S(){if(N.load){N.load.call(L[0],Q)}}function M(){P();S()}T=h(L[0]);if(T){O=new E();if(N.source.src){O=N.source}else{O.src=N.source}if(!O.complete&&N.load){O.onload=M}else{if(!P()){O.onload=M}else{S()}}}else{Q=t}return Q};u.fn.clearCanvas=function(M){var P=this,L,N,O=B(new A(),M);for(N=0;N<P.length;N+=1){L=h(P[N]);if(L){f(L,O,O.width,O.height);if(!O.width&&!O.height){L.clearRect(0,0,P[N].width,P[N].height)}else{L.clearRect(O.x-O.width/2,O.y-O.height/2,O.width,O.height)}}}return P};u.fn.saveCanvas=function(){var N=this,L,M;for(M=0;M<N.length;M+=1){L=h(N[M]);if(L){L.save()}}return N};u.fn.restoreCanvas=function(){var N=this,L,M;for(M=0;M<N.length;M+=1){L=h(N[M]);if(L){L.restore()}}return N};u.fn.scaleCanvas=function(M){var P=this,L,N,O=B(new A(),M);for(N=0;N<P.length;N+=1){L=h(P[N]);if(L){L.save();L.translate(O.x,O.y);L.scale(O.scaleX,O.scaleY);L.translate(-O.x,-O.y)}}return P};u.fn.translateCanvas=function(M){var P=this,L,N,O=B(new A(),M);for(N=0;N<P.length;N+=1){L=h(P[N]);if(L){L.save();L.translate(O.x,O.y)}}return P};u.fn.rotateCanvas=function(M){var P=this,L,N,O=B(new A(),M);for(N=0;N<P.length;N+=1){L=h(P[N]);if(L){f(L,O,0,0)}}return P};u.fn.drawRect=function(R){var M=this,U,Q,P=B(new A(),R),O,T,N,S,L;for(Q=0;Q<M.length;Q+=1){U=h(M[Q]);if(U){a(U,P);f(U,P,P.width,P.height);U.beginPath();if(P.cornerRadius){P.closed=s;O=P.x-P.width/2;T=P.y-P.height/2;N=P.x+P.width/2;S=P.y+P.height/2;L=P.cornerRadius;if((N-O)-(2*L)<0){L=(N-O)/2}if((S-T)-(2*L)<0){L=(S-T)/2}U.moveTo(O+L,T);U.lineTo(N-L,T);U.arc(N-L,T+L,L,3*d/2,d*2,I);U.lineTo(N,S-L);U.arc(N-L,S-L,L,0,d/2,I);U.lineTo(O+L,S);U.arc(O+L,S-L,L,d/2,d,I);U.lineTo(O,T+L);U.arc(O+L,T+L,L,d,3*d/2,I)}else{U.rect(P.x-P.width/2,P.y-P.height/2,P.width,P.height)}U.restore();if(P.event){F.call(M[Q],U,R)}o(U,P)}}return M};u.fn.drawArc=function(M){var P=this,L,N,O=B(new A(),M);if(!O.inDegrees&&O.end===360){O.end=d*2}for(N=0;N<P.length;N+=1){L=h(P[N]);if(L){a(L,O);f(L,O,O.radius*2,O.radius*2);L.beginPath();L.arc(O.x,O.y,O.radius,(O.start*O.toRad)-(d/2),(O.end*O.toRad)-(d/2),O.ccw);L.restore();if(O.event){F.call(P[N],L,M)}o(L,O)}}return P};u.fn.drawEllipse=function(M){var Q=this,L,O,P=B(new A(),M),N=P.width*4/3;for(O=0;O<Q.length;O+=1){L=h(Q[O]);if(L){a(L,P);f(L,P,P.width,P.height);L.beginPath();L.moveTo(P.x,P.y-P.height/2);L.bezierCurveTo(P.x-N/2,P.y-P.height/2,P.x-N/2,P.y+P.height/2,P.x,P.y+P.height/2);L.bezierCurveTo(P.x+N/2,P.y+P.height/2,P.x+N/2,P.y-P.height/2,P.x,P.y-P.height/2);L.restore();if(P.event){F.call(Q[O],L,M)}o(L,P)}}return Q};u.fn.drawLine=function(N){var S=this,M,Q,R=B(new A(),N),L=2,P=0,O=0;for(Q=0;Q<S.length;Q+=1){M=h(S[Q]);if(M){a(M,R);M.beginPath();M.moveTo(R.x1,R.y1);while(s){P=R["x"+L];O=R["y"+L];if(P!==v&&O!==v){M.lineTo(P,O);L+=1}else{break}}if(R.event){F.call(S[Q],M,N)}o(M,R)}}return S};u.fn.drawQuad=function(R){var L=this,U,Q,P=B(new A(),R),O=2,N=0,M=0,T=0,S=0;for(Q=0;Q<L.length;Q+=1){U=h(L[Q]);if(U){a(U,P);U.beginPath();U.moveTo(P.x1,P.y1);while(s){N=P["x"+O];M=P["y"+O];T=P["cx"+(O-1)];S=P["cy"+(O-1)];if(N!==v&&M!==v&&T!==v&&S!==v){U.quadraticCurveTo(T,S,N,M);O+=1}else{break}}if(P.event){F.call(L[Q],U,R)}o(U,P)}}return L};u.fn.drawBezier=function(W){var L=this,X,V,S=B(new A(),W),R=2,O=1,Q=0,P=0,U=0,N=0,T=0,M=0;for(V=0;V<L.length;V+=1){X=h(L[V]);if(X){a(X,S);X.beginPath();X.moveTo(S.x1,S.y1);while(s){Q=S["x"+R];P=S["y"+R];U=S["cx"+O];N=S["cy"+O];T=S["cx"+(O+1)];M=S["cy"+(O+1)];if(Q!==v&&P!==v&&U!==v&&N!==v&&T!==v&&M!==v){X.bezierCurveTo(U,N,T,M,Q,P);R+=1;O+=2}else{break}}if(S.event){F.call(L[V],X,W)}o(X,S)}}return L};u.fn.drawText=function(M){var P=this,L,N,O=B(new A(),M);for(N=0;N<P.length;N+=1){L=h(P[N]);if(L){a(L,O);L.textBaseline=O.baseline;L.textAlign=O.align;L.font=O.font;L.strokeText(O.text,O.x,O.y);L.fillText(O.text,O.x,O.y)}}return P};u.fn.drawImage=function(S){var L=this,V,N,R,P=B(new A(),S),Q,M;if(P.source.src){Q=P.source}else{if(P.source){Q=new E();Q.src=P.source}}function T(W){if(Q.complete===v||Q.complete===s){M=Q.width/Q.height;P.sWidth=P.sWidth||Q.width;P.sHeight=P.sHeight||Q.height;if(P.sWidth>Q.width){P.sWidth=Q.width}if(P.sHeight>Q.height){P.sHeight=Q.height}if(P.width===t&&P.sWidth!==Q.width){P.width=P.sWidth}if(P.height===t&&P.sHeight!==Q.height){P.height=P.sHeight}if(P.sx===t){if(P.cropFromCenter){P.sx=Q.width/2}else{P.sx=0}}if(P.sy===t){if(P.cropFromCenter){P.sy=Q.height/2}else{P.sy=0}}if(!P.cropFromCenter){P.sx+=P.sWidth/2;P.sy+=P.sHeight/2}if((P.sx+P.sWidth/2)>Q.width){P.sx=Q.width-P.sWidth/2}if((P.sx-P.sWidth/2)<0){P.sx=P.sWidth/2}if((P.sy-P.sHeight/2)<0){P.sy=P.sHeight/2}if((P.sy+P.sHeight/2)>Q.height){P.sy=Q.height-P.sHeight/2}if(P.width!==t&&P.height===t){S.height=P.height=P.width/M}else{if(P.width===t&&P.height!==t){S.width=P.width=P.height*M}else{if(P.width===t&&P.height===t){S.width=P.width=Q.width;S.height=P.height=Q.height}}}f(W,P,P.width,P.height);W.drawImage(Q,P.sx-P.sWidth/2,P.sy-P.sHeight/2,P.sWidth,P.sHeight,P.x-P.width/2,P.y-P.height/2,P.width,P.height);if(P.event){W.fillStyle="#000";W.beginPath();W.rect(P.x-P.width/2,P.y-P.height/2,P.width,P.height);W.restore();F.call(L[R],W,S);W.closePath()}else{W.restore()}return s}}function U(){if(P.load){P.load.call(N)}}function O(){T(V);U()}for(R=0;R<L.length;R+=1){N=L[R];V=h(L[R]);if(V){a(V,P);if(!Q.complete&&P.load){Q.onload=O}else{if(!T(V)){Q.onload=O}else{U()}}}}return L};u.fn.drawPolygon=function(S){var L=this,X,R,P=B(new A(),S),Y=d/P.sides,O=(d/2)+Y,W=(d*2)/P.sides,V=b(W/2)*P.radius,N,U,M,T,Q;P.closed=s;if(P.sides>2){for(R=0;R<L.length;R+=1){X=h(L[R]);if(X){a(X,P);f(X,P,P.radius,P.radius);X.beginPath();for(Q=0;Q<P.sides;Q+=1){N=P.x+G(P.radius*b(O));U=P.y+G(P.radius*n(O));if(Q===0){X.moveTo(N,U)}else{X.lineTo(N,U)}if(P.projection){M=P.x+G((V+V*P.projection)*b(O+Y));T=P.y+G((V+V*P.projection)*n(O+Y));X.lineTo(M,T)}O+=W}X.restore();if(P.event){F.call(L[R],X,S)}o(X,P)}}}return L};u.fn.setPixels=function(T){var L=this,V,N,S,Q,O=B(new A(),T),M,P,R,U={};for(S=0;S<L.length;S+=1){N=L[S];V=h(L[S]);if(V){if(!O.x&&!O.y&&!O.width&&!O.height){O.width=N.width;O.height=N.height;O.x=O.width/2;O.y=O.height/2}f(V,O,O.width,O.height);M=V.getImageData(O.x-O.width/2,O.y-O.height/2,O.width,O.height);P=M.data;R=P.length;U=[];if(O.each!==t){for(Q=0;Q<R;Q+=4){U.index=Q/4;U.r=P[Q];U.g=P[Q+1];U.b=P[Q+2];U.a=P[Q+3];O.each.call(N,U);P[Q]=U.r;P[Q+1]=U.g;P[Q+2]=U.b;P[Q+3]=U.a}}V.putImageData(M,O.x-O.width/2,O.y-O.height/2);V.restore()}}return L};function e(M,N){var L;for(L=0;L<M.length;L+=1){N[M[L]]=N["_"+M[L]]}}function g(M,N){var L;for(L=0;L<M.length;L+=1){N["_"+M[L]]=N[M[L]]}}y=["width","height","opacity"];z=["backgroundColor","color","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","fillStyle","strokeStyle","shadowColor"];function i(M){var O,P,N=[],L=1;if(typeof M==="object"){N=M}else{if(M.match(/^[a-z]+$/gi)){if(M==="transparent"){M="rgba(255,255,255,0)"}P=c.documentElement;O=P.style.color;P.style.color=M;M=u.css(P,"color");P.style.color=O}if(M.match(/^\#/gi)){if(M.length===4){M=M.replace(/([0-9a-f])/gi,"$1$1")}N=M.match(/[0-9a-f]{2}/gi);N[0]=m(N[0],16);N[1]=m(N[1],16);N[2]=m(N[2],16)}else{if(M.match(/^rgb/gi)){N=M.match(/[0-9\.]+/gi);if(M.match(/\%/gi)){L=2.55}N[0]=N[0]*L;N[1]=N[1]*L;N[2]=N[2]*L}}if(M.match("rgba")){N[3]=q(N[3])}else{N[3]=1}}return N}function J(M,L){M.now[L]=M.start[L]+(M.end[L]-M.start[L])*M.pos;if(L<3){M.now[L]=G(M.now[L])}}function D(L){if(typeof L.start!=="object"){L.start=i(L.start);L.end=i(L.end)}L.now=[];J(L,0);J(L,1);J(L,2);J(L,3);L.now="rgba("+L.now.join(",")+")";if(L.elem.style){L.elem.style[L.prop]=L.now}else{L.elem[L.prop]=L.now}}function k(L){var M;for(M=0;M<L.length;M+=1){if(!u.fx.step[L[M]]){u.fx.step[L[M]]=D}}}u.fn.getLayers=function(){var L=this[0],M;if(!L||!L.getContext){return t}M=u.data(L,"jCanvas-layers");if(!M){M=[];u.data(L,"jCanvas-layers",M)}return M};u.fn.getLayer=function(L){var O=this.getLayers(),N,M;if(!O){N=t}else{if(typeof L==="string"){for(M=0;M<O.length;M+=1){if(O[M].name===L){L=M;break}}}}L=L||0;N=O[L];return N};u.fn.addLayer=function(M){var R=this,L,Q=B(M,new A(),u.extend({},M)),P,N,O;Q.layer=s;for(O=0;O<R.length;O+=1){L=u(R[O]);if(h(R[O])){P=L.getLayers();if(typeof Q==="function"){Q.method="draw"}else{if(Q.method!=="drawImage"){Q.width=Q.width||0;Q.height=Q.width||0}for(N in H.events){if(H.events.hasOwnProperty(N)&&Q[N]){H.events[N].call(C,L,Q,P.length-1);Q.event=s}}}P.push(Q)}}R.drawLayers();return R};u.fn.removeLayers=function(){var N=this,M,L;for(L=0;L<N.length;L+=1){M=u(N[L]).getLayers()||[];M.length=0}return this};u.fn.removeLayer=function(L){var Q=this,P,N=typeof L,O,M;for(P=0;P<Q.length;P+=1){O=u(Q[P]).getLayers()||[];if(N==="string"){for(M=0;M<O.length;M+=1){if(O[M].name===L){O.splice(M,1);break}}}else{if(N==="number"){O.splice(L,1)}}}return this};u.fn.drawLayers=function(){var R=this,M,L,Q,P,O,N;for(O=0;O<R.length;O+=1){M=u(R[O]);L=h(M[0]);if(L){P=M.getLayers();L.clearRect(0,0,M[0].width,M[0].height);for(N=0;N<P.length;N+=1){Q=P[N];if(Q.visible){if(Q.method==="draw"){Q.call(M[0],L)}else{if(u.fn[Q.method]){u.fn[Q.method].call(M,Q)}}}}}}return R};u.fn.animateLayer=function(){var R=this,M,N=([]).slice.call(arguments,0),O,Q;if(typeof N[0]==="object"&&!N[0].layer){N.unshift(0)}if(N[2]===v){N.splice(2,0,t);N.splice(3,0,t);N.splice(4,0,function(){})}else{if(typeof N[2]==="function"){N.splice(2,0,t);N.splice(3,0,t)}}if(N[3]===v){N[3]=t;N.splice(4,0,function(){})}else{if(typeof N[3]==="function"){N.splice(3,0,t)}}if(N[4]===v){N[4]=function(){}}function L(S,T){return function(){e(y,T);S.drawLayers();N[4].call(S[0])}}function P(S,T){return function(){e(y,T);S.drawLayers()}}for(Q=0;Q<R.length;Q+=1){M=u(R[Q]);if(h(R[Q])){if(N[0].layer){O=N[0]}else{O=M.getLayer(N[0])}if(O&&O.method!=="draw"){g(y,O);g(y,N[1]);u(O).animate(N[1],{duration:N[2],easing:(u.easing[N[3]]?N[3]:t),complete:L(M,O),step:P(M,O)})}}}return R};u.event.fix=function(L){var M;L=j.call(u.event,L);if(L.pageX!==v&&L.offsetX===v){M=u(L.target).offset();if(M){L.offsetX=L.pageX-M.left;L.offsetY=L.pageY-M.top}}return L};k(z);u.support.canvas=(c.createElement("canvas").getContext!==v);H.defaults=w;H.prefs=K;H.extend=l;u.jCanvas=H}(jQuery,window,document,Math,Image,parseFloat,parseInt,true,false,null));
2  license.txt
... ...
@@ -1,4 +1,4 @@
1  
-Copyright (c) 2011 Caleb Evans, http://calebevans.me/projects/jcanvas/
  1
+Copyright 2012 Caleb Evans, http://calebevans.me/projects/jcanvas/
2 2
 
3 3
 Permission is hereby granted, free of charge, to any person obtaining
4 4
 a copy of this software and associated documentation files (the
8  readme.txt
... ...
@@ -1,5 +1,6 @@
1 1
 jCanvas
2  
-Caleb Evans
  2
+Copyright 2012, Caleb Evans
  3
+Licensed under the MIT license
3 4
 
4 5
 jCanvas is a JavaScript library that makes the HTML5 canvas easy to work with. It requires jQuery 1.4 or newer.
5 6
 
@@ -10,7 +11,4 @@ DOCUMENTATION
10 11
 http://calebevans.me/projects/jcanvas/docs.html
11 12
 
12 13
 SUPPORT
13  
-http://calebevans.me/projects/jcanvas/support.html
14  
-
15  
-LICENSE
16  
-http://calebevans.me/projects/jcanvas/about.html
  14
+http://calebevans.me/projects/jcanvas/support.html

0 notes on commit 5d5d325

Please sign in to comment.
Something went wrong with that request. Please try again.