Canvas Part 5

This time I’ve taking the actual drawing out of the canvas object so we can have different brushes. I’ve also included a bit of code to get the color from the current cell and compare it with a hex color.

First, here is the example.

Canvas Test 6


I included a drop down to change the brush time. I could have easily added another to change the color of each brush. In order for a brush to work, it must implement a onMouseDown, onMouseMove, and onMouseUp methods. These methods are then bound when the brush is set on the Grid.

In order to compare a color from the canvas to a hex color, I have to convert the PixalArrayData into it’s Hex equivalent. This is code I found off the internet. I’ve include the original URL in the source.

//
// Orginal From http://www.javascripter.net/faq/rgbtohex.htm
// Added PDAtoHex()
//
function PDAtoHex(pixalDataArray)
{
	return "#" + toHex(pixalDataArray[0]) + toHex(pixalDataArray[1]) + toHex(pixalDataArray[2]);
}
function toHex(N) {
 if (N==null) return "00";
 N=parseInt(N); if (N==0 || isNaN(N)) return "00";
 N=Math.max(0,N); N=Math.min(N,255); N=Math.round(N);
 return "0123456789ABCDEF".charAt((N-N%16)/16)
      + "0123456789ABCDEF".charAt(N%16);
}

//
// Simple Brush
//	Colors Primary on Click, Secondary if primary is already the color.
var SimpleDrawBrush = {
	//Colors used for the brush
	color1: "#00FF00",
	color2: "#FFFFFF",

	onMouseDown: function(evt){
		//We Used jQuery to bind it, so we are getting a jQuery object as this
		//Get the Cell from the grid
		var cell = Grid.getCellFromEvent(evt);

		//Get the current color of the cell.
		var color = Grid.getColorFromCell(cell);

		//Is it already the Primary color?
		if( PDAtoHex(color) == SimpleDrawBrush.color1 ){
			//Yes, use the secondary color
			Grid.drawCell(cell, SimpleDrawBrush.color2);
		} else {
			//Use the Primary Color
			Grid.drawCell(cell, SimpleDrawBrush.color1);
		}
	},

	onMouseMove: function(evt)
	{
		//Do nothing, this method just has to be defined.
	},

	onMouseUp: function(evt)
	{
		//Do nothing, this method just has to be defined.
	},

};

//
// Hold Brush
//	Keeps coloring for as long as the mouse in down.
var HoldDrawBrush = {
	//Color for the brush
	color1: "#FF0000",
	shouldDraw: false,

	//
	// Start the coloring process
	onMouseDown: function(evt)
	{
		//Get the Cell from the grid
		var cell = Grid.getCellFromEvent(evt);
		//Use the Primary Color
		Grid.drawCell(cell, HoldDrawBrush.color1);
		//Tell it we should be drawing
		HoldDrawBrush.shouldDraw = true;
	},

	//
	// Continue Coloring
	onMouseMove: function(evt)
	{
		if( HoldDrawBrush.shouldDraw )
		{
			//Get the Cell from the grid
			var cell = Grid.getCellFromEvent(evt);
			//Use the Primary Color
			Grid.drawCell(cell, HoldDrawBrush.color1);
		}
	},

	onMouseUp: function(evt)
	{
		//Stop drawing
		HoldDrawBrush.shouldDraw = false;
	},

};

//
// Line Brush
//
var LineBrush = {
	color1: "#0000FF",
	color2: "#FFFFFF",
	shouldDraw: false,
	startCell: {column: -1, row: -1},
	overCell: {column: -1, row: -1},

	onMouseDown: function(evt)
	{
		//Get the Cell from the grid
		LineBrush.startCell = Grid.getCellFromEvent(evt);
		//Use the Primary Color
		Grid.drawCell(LineBrush.startCell, LineBrush.color);
		//Tell it we should be drawing
		LineBrush.shouldDraw = true;
	},

	onMouseMove: function(evt)
	{
		if( LineBrush.shouldDraw )
		{
			// Erase the old line
			LineBrush.drawLine( LineBrush.color2 );

			//Get the Cell from the grid
			LineBrush.overCell = Grid.getCellFromEvent(evt);

			//Draw the new line
			LineBrush.drawLine( LineBrush.color1 );
		}
	},

	onMouseUp: function(evt)
	{
		//Stop drawing
		LineBrush.shouldDraw = false;
	},

	//
	// Draws a line from the start cell to the over cell.
	//
	drawLine: function(color)
	{
		//Save as varibles for ease of reading
		var a_column = LineBrush.startCell.column;
		var a_row = LineBrush.startCell.row;
		var b_column = LineBrush.overCell.column;
		var b_row = LineBrush.overCell.row;

		//Get the length of the line
		var line_length = Math.sqrt( Math.pow( a_column - b_column, 2) + Math.pow( a_row - b_row, 2));
		//Now draw each point
		for(var i=0; i < line_length; i++){
			//Get the Row/Column of the cell to color
			var cell = {};
			cell.column = Math.round( b_column + ( a_column - b_column)*i/line_length);
			cell.row = Math.round( b_row + ( a_row - b_row)*i/line_length);

			//Now redraw it
			Grid.drawCell( cell, color);
		}
	},
};

//
// Controls the Grid
var Grid = {
	canvasID: "display",	//ID for the canvas element
	display: null,			//The Drawing context
	jQueryCanvas: null,		//jQuery object for the canvas
	//Canvas Size
	canvasWidth: 500,
	canvasHeight: 400,
	//Columns and Rows
	numberOfColumns: 25,
	numberOfRows: 25,
	//Colors for the Grid
	backgroundColor: "#FFF",
	gridColor: "#ccf",
	gridThickness: "2",
	//Size of the cells
	cellWidth:  function() { return this.canvasWidth/this.numberOfColumns; },
	cellHeight: function() { return this.canvasHeight/this.numberOfRows; },

	//
	//Draw the Grid
	// Uses the gridColor and gridThickness
	drawGrid : function(){
		//Set the colors
		this.display.strokeStyle = this.gridColor;
		this.display.lineWidth = this.gridThickness;

		//Start Draw
		this.display.beginPath();

		//Draw the Vertical lines
		for(var i=0; i <= this.numberOfColumns; i++){
			//Move to the top of the canvas
			this.display.moveTo(i*this.cellWidth(), 0)
			//Draw the line
			this.display.lineTo( i*this.cellWidth(), this.canvasHeight );
		}

		//Draw the Horizontal lines.
		for(var i=0; i <= this.numberOfRows; i++){
			//Move to the left of the canvas
			this.display.moveTo(0, i*this.cellHeight())
			//Draw the line
			this.display.lineTo( this.canvasWidth, i*this.cellHeight() );
		}
		//Stop Draw
		this.display.stroke();
	},
	//
	//Draw the Background
	// Uses backgroundColor
	drawBackground : function(){
		this.display.fillStyle = this.backgroundColor;
		this.display.fillRect(0,0, this.canvasWidth, this.canvasHeight);
	},
	//
	//Draw/color a cell
	// Takes: Cell object with column,row
	drawCell : function(cell, color){
		//Figure out the position
		var y_pos = cell.row * this.cellHeight();
		var x_pos = cell.column * this.cellWidth();

		//Set the Color
		this.display.fillStyle = color;
		//Draw the cell
		this.display.fillRect( x_pos, y_pos, this.cellWidth(), this.cellHeight());
		//Draw the cell outline
		this.display.strokeRect( x_pos, y_pos, this.cellWidth(), this.cellHeight());
	},

	//
	//Get the Cell The Mouse is in
	// Returns: Cell object with column,row
	getCellFromEvent : function(evt){
		var offset = this.jQueryCanvas.offset();
		//Create an Object to hold the column/row
		var cell = {
			column: -1,
			row: -1,
		};

		//Find the poistion of the mouse
		var x_pos = Math.floor(evt.pageX - offset.left);
		var y_pos = Math.floor(evt.pageY - offset.top);

		//Now which column was it clicked?
		for(var column=0; column < this.numberOfColumns; column++){
			//Find the column
			if( x_pos >= column*this.cellWidth() && x_pos <= (column+1)*this.cellWidth() ){
				//Found it!
				cell.column = column;
				//Fow find the row
				for(var row=0; row < this.numberOfRows; row++){
					//Find the row
					if( y_pos >= row*this.cellHeight() && y_pos <= (row+1)*this.cellHeight()){
						//Found it!
						cell.row = row;
					}
				} //End Row
			}
		} // End Column

		//Return the found position
		return cell;
	},
	//
	//Gets the color of a cell
	// Returns: CanvasPixelArray
	getColorFromCell: function(cell){
		//Figure out the position
		var y_pos = cell.row * this.cellHeight();
		var x_pos = cell.column * this.cellWidth();

		return this.display.getImageData( x_pos+1, y_pos+1, 1, 1).data;
	},

	//
	//Initalize the Grid
	//
	init: function(){
		this.jQueryCanvas = $("#"+this.canvasID);

		this.jQueryCanvas.attr({
			width: this.canvasWidth,
			height: this.canvasHeight
		});

		//Set the Drawing context
		this.display = this.jQueryCanvas[0].getContext("2d");

		//Draw the Background
		this.drawBackground();
		//Draw the Grid
		this.drawGrid();
	},

	//
	// Set the Brush to Use
	//
	setBrush: function(brushObject)
	{
		this.jQueryCanvas
			//UnBind all the Old brush stuff
			.unbind("mousedown")
			.unbind("mousemove")
			.unbind("mouseup")
			//Bind our Grid to the Brushes Methods
			.bind("mousedown", brushObject.onMouseDown)
			.bind("mousemove", brushObject.onMouseMove)
			.bind("mouseup", brushObject.onMouseUp)
	},
};
Share

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

CommentLuv Enabled