Report abuse

<!DOCTYPE HTML> 
<html lang="en"> 
	<head> 
		<title>Harmony - Procedural drawing tool</title> 
		<meta charset="utf-8"> 
		<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
		<script type="text/javascript" src="colorpicker/js/jquery.js"></script>
		<script type="text/javascript" src="colorpicker/js/colorpicker.js"></script>
	  <script type="text/javascript" src="colorpicker/js/eye.js"></script>
	  <script type="text/javascript" src="colorpicker/js/utils.js"></script>
    <script type="text/javascript" src="colorpicker/js/layout.js?ver=1.0.2"></script> 
	  <link rel="stylesheet" href="colorpicker/css/colorpicker.css" type="text/css" />
    <link rel="stylesheet" media="screen" type="text/css" href="colorpicker/css/layout.css" />
		 
		<style type="text/css"> 
			* { color: #444; font-family:Monospace; font-size:12px; }
			body { background-color: #fff; margin: 0px; overflow: hidden; }
			#menu { position: absolute; width: 400px; background-color: #eee; margin: auto; padding: 5px 10px; text-align: center; text-transform: uppercase; visibility: hidden; }
			input, select { text-transform: uppercase; text-align:center; }
			#colorBoxes{ float: left; left:20px; top:0px; display:none;}
			#wrap{ background-color: #cf0;  z-index:50; position: absolute; left: 35px; top: 100px; visibility: hidden;}
			#container{z-index:-10;}
		</style> 
	</head> 
	<body> 

<!--		<script type="text/javascript"> 
		  var _gaq = _gaq || [];
		  _gaq.push(['_setAccount', 'UA-86951-7']);
		  _gaq.push(['_trackPageview']);

		  (function() {
		    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
		    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
		    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
		  })();
		</script> 
    <script type="text/javascript" charset="utf-8">

			
    </script>
-->  

		<div id="menu"><a href="http://mrdoob.com/blog/post/689" target="_blank">Harmony</a> 
					     <select id="selector"></select> <input id="save" type="button" value="Save"><input id="clear" type="button" value="Clear"><div id="dash">Default influence</div>
							<div id="colorSelector"><div style="background-color: #0000ff"></div>
							 <div id="colorBoxes">
							 <p><input type="text" maxlength="3" size="3" id="R" value="000" /></p>
							 <p><input type="text" maxlength="3" size="3" id="G" value="000" /></p>
							 <p><input type="text" maxlength="3" size="3" id="B" value="000" /></p>  </div>
								
							</div>
							<p><input type="button" id="toggle" value="Hide Content"/></p>   
							<p><label id="edit" for="eraserSize">Eraser Size :</label><input type="text" size="3" id="eraserSize" value="10" /></p>
			 </div>
		<div id="overlay">
			<div id="wrap">           
				<h1 class="title">
				 	Testing in overlaying, canvas element. 
				</h1>
			   
			</div>
		</div>
		<div id="container">

		</div> 

		<script type="text/javascript"> 

			// Sketchy, Shaded, Chrome, Fur, LongFur and Web are variations of the idea of connecting neightbour points
			// first implemented (afaik) by Ze Frank's The Scribbler (http://www.zefrank.com/scribbler/)

			// This code uses the MIT license:
			// http://www.opensource.org/licenses/mit-license.php

			var STYLES = ["eraser","sketchy", "shaded", "chrome", "fur", "longfur", "web", "", "squares", "ribbon", "", "circles", "grid"];

			var SCREEN_WIDTH = window.innerWidth;
			var SCREEN_HEIGHT = window.innerHeight;

			var container, menu, selector;
			var saveButton, clearButton, toggleButton;
			var canvas, context;
			var style;
            var dash;
			var wrap;
			var mouseX = 0, mouseY = 0;
			var isMenuMouseOver = false, isMouseDown = false;
			
			//Marco: Keycapture stuff
			var _key = 0;
			
			var _influence = {
			  sketch: { low: 250, medium: 1000, large: 4000, xl: 6000,def: 4000 }
			}
			
			
			function init()
			{ 
				
				dash = document.getElementById('dash');
				
				container = document.getElementById('container');

				
				wrap = document.getElementById('wrap');
				wrap.style.visibility = 'hidden';
				wrap.style.width = (SCREEN_WIDTH / 2) + 'px' ;
				wrap.style.left = ((SCREEN_WIDTH - wrap.offsetWidth) / 2) + 'px';
				 
				menu = document.getElementById('menu');
				menu.style.left = ((SCREEN_WIDTH - menu.offsetWidth) / 2) + 'px';
				menu.style.visibility = 'visible';
				menu.addEventListener('mouseover', onMenuMouseOver, false);
				menu.addEventListener('mouseout', onMenuMouseOut, false);

				canvas = document.createElement("canvas");
				canvas.width = SCREEN_WIDTH;
				canvas.height = SCREEN_HEIGHT;
				canvas.style.cursor = 'crosshair';
				container.appendChild(canvas);

				context = canvas.getContext("2d");
				context.fillStyle = "rgb(255, 255, 255)";
				context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); 
				

				saveButton = document.getElementById('save');
				saveButton.addEventListener('click', save, false);

				clearButton = document.getElementById('clear');
				clearButton.addEventListener('click', clear, false);

				selector = document.getElementById('selector');
				selector.addEventListener('change', onSelectorChange, false);

				for (var i = 0; i < STYLES.length; i++)
				{
					var option = document.createElement("option");
					option.id = i;
					option.innerHTML = STYLES[i].toUpperCase();
					selector.appendChild(option);
				}


				if (window.location.hash)
				{
					var hash = window.location.hash.substr(1,window.location.hash.length);

					for (var i = 0; i < STYLES.length; i++)
					{
						if (hash == STYLES[i])
						{
							style = eval("new " + STYLES[i] + "(context)");
							selector.selectedIndex = i;
							break;
						}
					}
				}

				if (!style)
				{
					style = eval("new " + STYLES[0] + "(context)");
				}

				document.onmousedown = onDocumentMouseDown;
				document.onmouseout = onCanvasMouseUp;
				
				//Marco: Key event
                document.onkeydown = KeyCheck;

				canvas.onmousedown = onCanvasMouseDown;
				canvas.onmouseup = onCanvasMouseUp;
				canvas.onmousemove = onCanvasMouseMove;

				canvas.ontouchstart = onCanvasTouchStart;
				canvas.ontouchend = onCanvasTouchEnd;
				canvas.ontouchmove = onCanvasTouchMove;
			}

			//Marco: Pass the pressed key to the global.
 			function KeyCheck(e) {
				_key = e.keyCode;
			    if(_key == "49") { dash.innerHTML = "low influence"; }
				if(_key == "50") { dash.innerHTML = "medium influence"; }
				if(_key == "51") { dash.innerHTML = "large influence"; }
				if(_key == "52") { dash.innerHTML = "XL influence"; }
			}
			
			
			function onDocumentMouseDown(e)
			{
				return isMenuMouseOver;
			}

			function onSelectorChange(e)
			{
				if (STYLES[selector.selectedIndex] == "")
					return;

				style.destroy();
				style = eval("new " + STYLES[selector.selectedIndex] + "(context)");

				window.location.hash = STYLES[selector.selectedIndex];
			}

			function onMenuMouseOver(e)
			{
				isMenuMouseOver = true;
			}

			function onMenuMouseOut(e)
			{
				isMenuMouseOver = false;
			}

			function ondocumentMouseDown(e)
			{
				return !isMenuMouseOver;
			}

			function onCanvasMouseDown(e)
			{
				isMouseDown = true;

				style.strokeStart( mouseX, mouseY );
			}

			function onCanvasMouseUp(e)
			{
				isMouseDown = false;

				style.strokeEnd( mouseX, mouseY );
			}

			function onCanvasMouseMove(e)
			{
				if (!e) var e = window.event;
				mouseX = e.clientX;
				mouseY = e.clientY;

				if (!isMouseDown)
					return;

				style.stroke( mouseX, mouseY );
			}

			function onCanvasTouchStart(e)
			{
				if(e.touches.length == 1)
				{
					var touch = e.touches[0];
					style.strokeStart( touch.pageX, touch.pageY );
				}

				return false;
			}

			function onCanvasTouchEnd(e)
			{
				if(e.touches.length == 1)
				{
					var touch = e.touches[0];
					style.strokeEnd( touch.pageX, touch.pageY );
				}
			}

			function onCanvasTouchMove(e)
			{
				if(e.touches.length == 1)
				{
					var touch = e.touches[0];
					style.stroke( touch.pageX, touch.pageY );
				}
			}

			function save()
			{
				window.open(canvas.toDataURL("image/png"),'mywindow');
			}

			
			 function clear()
			{ 
				var cR = $("#R").val();
				var cG = $("#G").val();
				var cB = $("#B").val();
				
				context.globalCompositeOperation = 'source-over';
				context.fillStyle = "rgb("+cR+","+cG+","+cB+")";
				context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

				style = eval("new " + STYLES[selector.selectedIndex] + "(context)");

				points = new Array();
				count = 0;
			} 


			// SAVING MY POOR SERVER :S (These classes are supposed to be on external files)

			function chrome( context )
			{
				this.init( context );
			}

			chrome.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
		
					if (RegExp(" AppleWebKit/").test(navigator.userAgent))
						this.context.globalCompositeOperation = 'darker';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{  
					var cR = $("#R").val();
					var cG = $("#G").val();
					var cB = $("#B").val();
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba("+cR+","+cG+","+cB+", 0.1)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					for (var i = 0; i < this.points.length; i++)
					{
						var size = 0.2;
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 1000)
						{
							this.context.strokeStyle = "rgba(" + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 0.1 )";
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0] + (dx * size), this.points[this.count][1] + (dy * size));
							this.context.lineTo( this.points[i][0] - (dx * size), this.points[i][1] - (dy * size));
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function circles( context )
			{
				this.init( context );
			}

			circles.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					var dx = mouseX - this.prevMouseX;
					var dy = mouseY - this.prevMouseY;
					var d = Math.sqrt(dx * dx + dy * dy) * 2;
					var d_half = d / 2;

					var cx = Math.floor(mouseX / 100) * 100 + 50;
					var cy = Math.floor(mouseY / 100) * 100 + 50;

					var steps = Math.floor( Math.random() * 10 );
					var step_delta = d / steps;

					for (var i = 0; i < steps; i++)
					{
						this.context.strokeStyle = "rgba(0, 0, 0, 0.1)";
						this.context.beginPath();
						this.context.arc( cx, cy, (steps - i) * step_delta, 0, Math.PI*2, true);
						this.context.stroke();
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function fur( context )
			{
				this.init( context );
			}

			fur.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{  
					var cR = $("#R").val();
					var cG = $("#G").val();
					var cB = $("#B").val();
					
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba("+ cR +","+ cG +","+ cB +", 0.1)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					for (var i = 0; i < this.points.length; i++)
					{
						var size = 0.5;
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 2000 && Math.random() > d / 2000)
						{
							this.context.strokeStyle = "rgba("+ cR +","+ cG +","+ cB +", 0.1)";
							this.context.beginPath();
							this.context.moveTo( mouseX + (dx * size), mouseY + (dy * size));
							this.context.lineTo( mouseX - (dx * size), mouseY - (dy * size));
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function grid( context )
			{
				this.init( context );
			}

			grid.prototype =
			{
				context: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;

					if (RegExp(" AppleWebKit/").test(navigator.userAgent))
						this.context.globalCompositeOperation = 'darker';

					this.context.strokeStyle = "rgba( 0, 0, 0, 0.01 )";
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
				},

				stroke: function( mouseX, mouseY )
				{
					var cx = Math.round(mouseX / 100) * 100;
					var cy = Math.round(mouseY / 100) * 100;

					var dx = (cx - mouseX) * 10;
					var dy = (cy - mouseY) * 10;

					for (var i = 0; i < 50; i++)
					{
						this.context.beginPath();
						this.context.moveTo( cx, cy );
						this.context.quadraticCurveTo(mouseX + Math.random() * dx, mouseY + Math.random() * dy, cx, cy);
						this.context.stroke();
					}
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function longfur( context )
			{
				this.init( context );
			}

			longfur.prototype =
			{
				context: null,

				points: null, count: null,

				init: function( context )
				{ 
					var cR = $("#R").val();
					var cG = $("#G").val();
					var cB = $("#B").val();
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';
					this.context.strokeStyle = "rgba("+ cR +","+ cG +","+ cB +", 0.05 )";
		
					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
				},

				stroke: function( mouseX, mouseY )
				{ 
					var cR = $("#R").val();
					var cG = $("#G").val();
					var cB = $("#B").val();          
					
					this.context.strokeStyle = "rgba("+ cR +","+ cG +","+ cB +", 0.05 )";
					this.points.push( [ mouseX, mouseY ] );

					for (var i = 0; i < this.points.length; i++)
					{
						var size = -Math.random();
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 4000 && Math.random() > d / 4000)
						{
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0] + (dx * size), this.points[this.count][1] + (dy * size));
							this.context.lineTo( this.points[i][0] - (dx * size) + Math.random() * 2, this.points[i][1] - (dy * size) + Math.random() * 2);
							this.context.stroke();
						}
					}
		
					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function ribbon( context )
			{
				this.init( context );
			}

			ribbon.prototype =
			{
				context: null,

				mouseX: null, mouseY: null,

				painters: null,

				interval: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.strokeStyle = "rgba( 0, 0, 0, 0.05 )";
					this.context.globalCompositeOperation = 'source-over';

					this.mouseX = SCREEN_WIDTH / 2;
					this.mouseY = SCREEN_HEIGHT / 2;

					this.painters = new Array();
		
					for (var i = 0; i < 50; i++)
					{
						this.painters.push({ dx: SCREEN_WIDTH / 2, dy: SCREEN_HEIGHT / 2, ax: 0, ay: 0, div: 0.1, ease: Math.random() * 0.2 + 0.6 });
					}
		
					this.isDrawing = false;

					this.interval = setInterval( bargs( function( _this ) { _this.update(); return false; }, this ), 1000/60 );
				},
	
				destroy: function()
				{
					clearInterval(this.interval);
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.mouseX = mouseX;
					this.mouseY = mouseY

					for (var i = 0; i < this.painters.length; i++)
					{
						this.painters[i].dx = mouseX;
						this.painters[i].dy = mouseY;
					}

					this.shouldDraw = true;
				},

				stroke: function( mouseX, mouseY )
				{
					this.mouseX = mouseX;
					this.mouseY = mouseY;
				},

				strokeEnd: function( mouseX, mouseY )
				{
	
				},

				update: function()
				{
					for (var i = 0; i < this.painters.length; i++)
					{
						this.context.beginPath();
						this.context.moveTo(this.painters[i].dx, this.painters[i].dy);		

						this.painters[i].dx -= this.painters[i].ax = (this.painters[i].ax + (this.painters[i].dx - this.mouseX) * this.painters[i].div) * this.painters[i].ease;
						this.painters[i].dy -= this.painters[i].ay = (this.painters[i].ay + (this.painters[i].dy - this.mouseY) * this.painters[i].div) * this.painters[i].ease;
						this.context.lineTo(this.painters[i].dx, this.painters[i].dy);
						this.context.stroke();
					}
				}
			}

			function bargs( _fn )
			{
				var args = [];
				for( var n = 1; n < arguments.length; n++ )
					args.push( arguments[ n ] );
				return function () { return _fn.apply( this, args ); };
			}

			function shaded( context )
			{
				this.init( context );
			}

			shaded.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{  
					var cR = $("#R").val();
					var cG = $("#G").val();
					var cB = $("#B").val();
					
					this.points.push( [ mouseX, mouseY ] );

					for (var i = 0; i < this.points.length; i++)
					{
						var size = 0.3;
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 1000)
						{
							this.context.strokeStyle = "rgba("+ cR +","+cG+","+cB+", " + ((1 - (d / 1000)) * 0.1) + " )";

							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0], this.points[this.count][1]);
							this.context.lineTo( this.points[i][0], this.points[i][1]);
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function sketchy( context )
			{
				this.init( context );
			}

			sketchy.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{  
						var cR = $("#R").val();
						var cG = $("#G").val();
						var cB = $("#B").val();
					
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba("+cR+","+cG+","+cB+", 0.05)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					this.context.strokeStyle = "rgba("+cR+","+cG+","+cB+", 0.05 )";

					var inf = _influence.sketch.def;
					for (var i = 0; i < this.points.length; i++)
					{
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;
						
 						//Marco: Just testing- need to integrate more.
					    
				
						if (_key == 49) { inf = _influence.sketch.low;  }
						if (_key == 50) { inf = _influence.sketch.medium;} 
						if (_key == 51) { inf = _influence.sketch.large;}
						if (_key == 52) { inf = _influence.sketch.xl;}
					
						if (d < inf && Math.random() > d / 2000)
						{
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0] + (dx * 0.3), this.points[this.count][1] + (dy * 0.3));
							this.context.lineTo( this.points[i][0] - (dx * 0.3), this.points[i][1] - (dy * 0.3));
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function squares( context )
			{
				this.init( context );
			}

			squares.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				init: function( context )
				{
					this.context = context;
					this.context.globalCompositeOperation = 'source-over';
					this.context.strokeStyle = "rgba(0, 0, 0, 1)";
					this.context.fillStyle = "rgba(255, 255, 255, 1)";
					this.context.lineWidth = 1;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					var dx = mouseX - this.prevMouseX;
					var dy = mouseY - this.prevMouseY;

					var angle = 1.57079633;

					var px = Math.cos(angle) * dx - Math.sin(angle) * dy;
					var py = Math.sin(angle) * dx + Math.cos(angle) * dy ;

					this.context.beginPath();
					this.context.moveTo(this.prevMouseX - px, this.prevMouseY - py);
					this.context.lineTo(this.prevMouseX + px, this.prevMouseY + py);
					this.context.lineTo(mouseX + px, mouseY + py);
					this.context.lineTo(mouseX - px, mouseY - py);
					this.context.lineTo(this.prevMouseX - px, this.prevMouseY - py);
					this.context.fill();
					this.context.stroke();

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function web( context )
			{
				this.init( context );
			
			}

			web.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{  
					var cR = $("#R").val();
					var cG = $("#G").val();
					var cB = $("#B").val();
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba("+cR+","+cG+","+cB+", 0.5)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					this.context.strokeStyle = "rgba("+cR+","+cG+","+cB+", 0.1)";

					for (var i = 0; i < this.points.length; i++)
					{
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 2500 && Math.random() > 0.9)
						{
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0], this.points[this.count][1]);
							this.context.lineTo( this.points[i][0], this.points[i][1]);
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			} 
			
			function eraser( context )
			{
				this.init( context );
			}

			eraser.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,
				

				init: function( context )
				{ 
					this.context = context;
					this.context.lineWidth = 1;

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{ 
					var eraserSize = $('#eraserSize').val();
					var cR = $("#R").val();
					var cG = $("#G").val();
					var cB = $("#B").val();
					
				 
					
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba("+ cR +","+ cG +","+ cB +", 0.5)";
					this.context.lineWidth = eraserSize;
					this.context.lineCap = "round";
					this.context.lineJoin = "round";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();
 					
					this.prevMouseX = mouseX;
  				this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			init(); // heh!
	
		</script> 
	</body> 
</html>