HTML 5 Canvas – Chess board

My next HTML5 project to take advantage of the canvas element will attempt to draw the traditional chess board. The pieces will then be drawn from a sprite map. Finally, one’s intention is to implement a mouse-click handler, so you can click and move the pieces. This will not be a fully functional chess game, my aim is to prove the concept and explain the steps involved to produce a prototype. One day I may return to the project to implement the full rule-set; however, time-scales prevent me from achieving this at the moment. Let’s start by looking at the end product and then we will look at the source code.

html5 canvas chess board

The HTML Source

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<title>HTML5 Canvas - Chess board</title>
		<script src='chess_board.js'></script>
	</head>
	<body onload='draw();'>
		<div>
			<canvas id="chess" width="800" height="800"></canvas>
		</div>
	</body>
</html>
The HTML is straight forward. The items of interest are the canvas element and the ‘onload’ event for the body. For those who are not familiar with HTML let me explain how we draw the chess board and pieces onto the canvas. When any HTML page loads the browser will run the JavaScript code attached to the onload event of the body tag e.g.
	<body onload='draw();'>
In order to understand how the ‘draw’ function works we need to understand how the browsers locates it. The browser will load any JavaScript code included in-line or within any script tags prior to displaying the page to the user e.g.
	<script src='chess_board.js'></script>
Therefore, the content of the script “chess_board.js” will be loaded, and thus, the function called ‘draw’ will be available. If you were to look inside the aforementioned script you will be able to see the code e.g.
function draw()
{
	// Main entry point got the HTML5 chess board example
	canvas = document.getElementById('chess');

	// Canvas supported?
	if(canvas.getContext)
	{
		ctx = canvas.getContext('2d');

		// Calculdate the precise block size
		BLOCK_SIZE = canvas.height / NUMBER_OF_ROWS;
		
		// Draw the background
		drawBoard();

		defaultPositions();
		
		// Draw pieces
		pieces = new Image();
		pieces.src = 'pieces.png';
		pieces.onload = drawPieces;

		canvas.addEventListener('click', board_click, false);
	}
	else
	{
		alert("Canvas not supported!");
	}
}

The content of the function is quite readable and the code is ordered in logic steps. The first step is to obtain a handle to the canvas element. If the canvas element is found we then proceed to ensure the browser supports the canvas. Assuming support is implemented the second step is to calculate the dimensions for the height and width of one block within the chess board e.g.
    // Calculdate the precise block size
    BLOCK_SIZE = canvas.height / NUMBER_OF_ROWS;
The next step is to draw the board. The code for this is within the function ‘drawBoard’. This function contains the following:
function drawBoard()
{	
	for(iRowCounter = 0; iRowCounter < NUMBER_OF_ROWS; iRowCounter++)
	{
		drawRow(iRowCounter);
	}	
	
	// Draw outline
	ctx.lineWidth = 3;
	ctx.strokeRect(0, 0, NUMBER_OF_ROWS * BLOCK_SIZE, NUMBER_OF_COLS * BLOCK_SIZE);	
}
The chess board is 8 rows by 8 columns. The source above iterates through each of the 8 rows – top to bottom. Each row is handle by the function ‘drawRow’:
function drawRow(iRowCounter)
{
	// Draw 8 block left to right
	for(iBlockCounter = 0; iBlockCounter < NUMBER_OF_ROWS; iBlockCounter++)
	{
		drawBlock(iRowCounter, iBlockCounter);
	}
}
Each time the function is called it draws 8 blocks left-to-right

chess-piece-drawing-the-board

Each block is drawn within the function ‘drawBlock’:
function drawBlock(iRowCounter, iBlockCounter)
{	
	// Set the background
	ctx.fillStyle = getBlockColour(iRowCounter, iBlockCounter);
	
	// Draw rectangle for the background
	ctx.fillRect(iRowCounter * BLOCK_SIZE, iBlockCounter * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);

	ctx.stroke();	
}
Within this function the colour of the block is set and the rectangle that represents one block is drawn. The function to calculate the colour follows:
function getBlockColour(iRowCounter, iBlockCounter)
{
	var cStartColour;
	
	// Alternate the block colour
	if(iRowCounter % 2)
		cStartColour = (iBlockCounter % 2?BLOCK_COLOUR_1:BLOCK_COLOUR_2);
	else
		cStartColour = (iBlockCounter % 2?BLOCK_COLOUR_2:BLOCK_COLOUR_1);
		
	return cStartColour;
}
The function uses JavaScript’s Mod operator to determine the colour. Rows which have an odd number colours the first block using the darker colour and then toggles between the light and dark for each subsequent block. Even rows start on the lighter colour. That concludes the logic to draw the games board.


The next step within the ‘draw’ function deals with drawing the pieces. This is achieved by the following lines:

	defaultPositions();
		
	// Draw pieces
	pieces = new Image();
	pieces.src = 'pieces.png';
	pieces.onload = drawPieces;

	canvas.addEventListener('click', board_click, false);

The function ‘defaultPositions’ configures a data-structure that represents the games state:
function defaultPositions()
{
	json = 
	{
		"white": 
		[
			{
				"piece": PIECE_CASTLE,
				"row": 0,
				"col": 0,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_ROUKE,
				"row": 0,
				"col": 1,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_BISHOP,
				"row": 0,
				"col": 2,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_KING,
				"row": 0,
				"col": 3,
				"status": IN_PLAY
			},	
			{
				"piece": PIECE_QUEEN,
				"row": 0,
				"col": 4,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_BISHOP,
				"row": 0,
				"col": 5,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_ROUKE,
				"row": 0,
				"col": 6,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_CASTLE,
				"row": 0,
				"col": 7,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 0,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 1,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 2,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 3,
				"status": IN_PLAY
			},	
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 4,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 5,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 6,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 1,
				"col": 7,
				"status": IN_PLAY
			}
		],
		"black": 
		[
			{
				"piece": PIECE_CASTLE,
				"row": 7,
				"col": 0,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_ROUKE,
				"row": 7,
				"col": 1,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_BISHOP,
				"row": 7,
				"col": 2,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_KING,
				"row": 7,
				"col": 3,
				"status": IN_PLAY
			},	
			{
				"piece": PIECE_QUEEN,
				"row": 7,
				"col": 4,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_BISHOP,
				"row": 7,
				"col": 5,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_ROUKE,
				"row": 7,
				"col": 6,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_CASTLE,
				"row": 7,
				"col": 7,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 0,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 1,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 2,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 3,
				"status": IN_PLAY
			},	
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 4,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 5,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 6,
				"status": IN_PLAY
			},
			{
				"piece": PIECE_PAWN,
				"row": 6,
				"col": 7,
				"status": IN_PLAY
			}
		]		
	};
}
The data-structure uses JavaScript object notation (JSON) to define each team and each piece within the teams. The extract below shows the properties assigned to each piece. These are the piece’s identity, its location and the game state of the piece – whether it is in play or not:
{
	"piece": PIECE_CASTLE,
	"row": 0,
	"col": 0,
	"status": IN_PLAY
}
Following the configuration of the game state data-structure an image containing the chess pieces is loaded:
	// Draw pieces
	pieces = new Image();
	pieces.src = 'pieces.png';
This image includes each piece:

Chess pieces

Each piece occupies a 100px by 100px square with a transparent background. The order of the pieces is significant: its position relates to the piece identity used in the game state data-structure. These constants are declared at the top of the JavaScript file:
var PIECE_PAWN = 0,
PIECE_CASTLE = 1,
PIECE_ROUKE = 2,
PIECE_BISHOP = 3,
PIECE_QUEEN = 4,
PIECE_KING = 5;
These constants are used to locate the correct piece from the image. The image part is then drawn onto the canvas in the position stored within the column and row attribute of the piece. The logic to draw each piece is performed after the image containing the pieces is loaded. This is achieved by the followed event:
pieces.onload = drawPieces;
This line instructs the browser to call the ‘drawPieces’ function once the image resource has loaded. It contains the following:
function drawPieces()
{
	drawTeamOfPieces(json.black, true);
	drawTeamOfPieces(json.white, false);
}
The logic for drawing both teams is identical. Thus, this function does nothing more than call the ‘drawTeamOfPieces’ function for each team. This function accepts two parameters. These are the data-structure holding the team information, followed by a boolean value to indicate which team the data-structure relates to. The function contains the following:
function drawTeamOfPieces(teamOfPieces, bBlackTeam)
{
	var iPieceCounter;

	// Loop through each piece and draw it on the canvas	
	for (iPieceCounter = 0; iPieceCounter < teamOfPieces.length; iPieceCounter++) 
	{	
		drawPiece(teamOfPieces[iPieceCounter], bBlackTeam);
	}	
}
We loop around each piece for the given team and call the ‘drawPiece’ function for each. This function also accepts two parameters; the piece identity and the same boolean flag passed into the outer function as discussed above. The ‘drawPiece’ function contains the following:
function drawPiece(curPiece, bBlackTeam)
{
	var imageCoords = getImageCoords(curPiece.piece, bBlackTeam)
		
	// Draw the piece onto the canvas
	ctx.drawImage(pieces, 
		imageCoords.x, imageCoords.y, BLOCK_SIZE, BLOCK_SIZE,
		curPiece.col * BLOCK_SIZE, curPiece.row * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
					
}
To draw any given piece we need to perform two actions. The first is to obtain the coordinates of the piece within the sprite image map (which 100px by 100px tile do we need). The second step is to use these coordinates to draw the correct piece onto the board in the correct position. The coordinates for the source image (the chess piece) are calculated within the function called ‘getImageCoords’. This accepts the same two parameters as this ‘drawPiece’ function: the identity and team flag. The ‘getImageCoords’ function contains the following:
function getImageCoords(pieceCode, bBlackTeam)
{
	var imageCoords = 
	{
		"x": pieceCode * BLOCK_SIZE,
		"y": (bBlackTeam?0:BLOCK_SIZE)
	}; 
	
	return imageCoords;
}
The x pixel position within the image sprite map for any give piece can be obtained using the pieces identity. As mentioned earlier the order in which the chess pieces are drawn (from left-to-right) within the spite map is significant. The x coordinate for any piece is determine by multiplying the piece’s identity with the BLOCK_SIZE variable (100 pixels). The y pixel location is governed by the team the piece belongs too. The y position of all of the black pieces is 0 and the white pieces is the BLOCK_SIZE variable (100 pixels). This is obtained used the ternary operator (bBlackTeam?0:BLOCK_SIZE). Both of these values are then stored in a data-structure which is returned to the calling interface. The coordinates within the data-structure are then used to draw the image onto the canvas:

	// Draw the piece onto the canvas
	ctx.drawImage(pieces, 
		imageCoords.x, imageCoords.y, BLOCK_SIZE, BLOCK_SIZE,
		curPiece.col * BLOCK_SIZE, curPiece.row * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
					
To draw the piece onto the canvas we use the in-built canvas function ‘drawImage’. This accepts several parameters. The first parameter is the image source – in this case, this is the image containing all of the chess pieces. The next four parameters relate to the source image (parameter one). They represent the portion of the source image to draw onto the canvas. In our case we use the coordinates returned from ‘getImageCoords’ function as the x and y parameters, along with the height and width which are both set to the BLOCK_SIZE variable (100px). The final four parameters relate to the location (x,y) and size (width, height) that will be used to draw the current piece. An illustration of this follows:

chess-piece-drawing-a-piece

On completion of the ‘drawPieces’ function we are ready to start the game! At this point I originally planned on stopping development of this post; however, I was intrigued in how one would handle the user piece selection and movement. I therefore decided to implement the click and move logic for the pawn.
canvas.addEventListener('click', board_click, false);
The eagle-eyed of you may have noticed I skipped over the line above which is present in the main ‘draw’ function. This instructs the browser to monitor the ‘click’ action of the canvas and when detected calls the function ‘board_click’. This allow us to react to every users click. This includes the following:
function board_click(ev) 
{
	var x = ev.clientX - canvas.offsetLeft;
	var y = ev.clientY - canvas.offsetTop;

	var clickedBlock = screenToBlock(x, y);
	
	if(selectedPiece == null)
	{
		checkIfPieceClicked(clickedBlock);
	}
	else
	{
		processMove(clickedBlock);
	}
}
<div>This function controls the game's state.  A player can do one of two things at anyone time.  They can either choose a piece to move, or, choose a target square that the selected piece should be move too.  These actions must be done serially.  Thus, when the games first starts the expected action is for a player to select a chess piece.  This state is controlled by the global variable 'selectedPiece'.  A value of null means that no piece has been selected.  In this case the 'checkIfPieceClicked' function will be called.</div>

function checkIfPieceClicked(clickedBlock)
{
	var pieceAtBlock = getPieceAtBlock(clickedBlock);
	
	if (pieceAtBlock !== null)
	{
		selectPiece(pieceAtBlock);
	}
}
This function determines whether a piece is present within the block that the user has clicked. The logic for this click detection is contained within the ‘getPieceAtBlock’ function:
function getPieceAtBlock(clickedBlock)
{
	var team = (currentTurn === BLACK_TEAM ? json.black:json.white);

	return getPieceAtBlockForTeam(team, clickedBlock);
}
This function simply determines the correct data-structure for the team whose turn it is and passed this, along with the clickBlock to the function ‘getPieceAtBlockForTeam’:
function getPieceAtBlockForTeam(teamOfPieces, clickedBlock)
{
	var curPiece = null,
		iPieceCounter = 0,
		pieceAtBlock = null;
	
	for (iPieceCounter = 0; iPieceCounter < teamOfPieces.length; iPieceCounter++) 
	{
		curPiece = teamOfPieces[iPieceCounter];
		
		if (curPiece.status === IN_PLAY &&
			curPiece.col === clickedBlock.col &&
			curPiece.row === clickedBlock.row)
		{
			curPiece.position = iPieceCounter;
			
			pieceAtBlock = curPiece;
			iPieceCounter = teamOfPieces.length;
		}
	}
	
	return pieceAtBlock;
}
This function contains the logic required to deduce whether the user has clicked a piece. The pieces within the data-structure are assessed one-by-one to determine whether they are within the clicked block (column and row match that of the clickedBlock variable) and the piece is still in play. If a piece matches these conditions it is stored and returned to the calling interface. The calling interface in this scenario is the function ‘checkIfPieceClicked’ as shown above. This function then passes the return value (if it is not null) to the ‘selectPiece’ function:
function selectPiece(pieceAtBlock)
{
	// Draw outline
	ctx.lineWidth = SELECT_LINE_WIDTH;
	ctx.strokeStyle = HIGHLIGHT_COLOUR;
	ctx.strokeRect((pieceAtBlock.col * BLOCK_SIZE) + SELECT_LINE_WIDTH,
		(pieceAtBlock.row * BLOCK_SIZE) + SELECT_LINE_WIDTH, 
		BLOCK_SIZE - (SELECT_LINE_WIDTH * 2), 
		BLOCK_SIZE - (SELECT_LINE_WIDTH * 2));
	
	selectedPiece = pieceAtBlock;
}
This function draws a red outline within the clicked block e.g.

selected chess piece

After the outline has been applied the selected block is stored in the global variable ‘selectedPiece’.

This changes the logic within ‘board_click’, resulting in the function called ‘processMove’ being called when the user next clicks the board.
function processMove(clickedBlock)
{
	var pieceAtBlock = getPieceAtBlock(clickedBlock),
		enemyPiece = blockOccupiedByEnemy(clickedBlock);
	
	if (pieceAtBlock !== null)
	{
		removeSelection(selectedPiece);
		checkIfPieceClicked(clickedBlock);			
	}
	else if (canSelectedMoveToBlock(selectedPiece, clickedBlock, enemyPiece) === true)
	{
		movePiece(clickedBlock, enemyPiece);
	}
}
The function can either do one of two things. The first check determines whether the user has clicked an alternate piece, indicating they wish to move a difference piece. On detection of this the function simply calls the ‘removeSelection’ function followed by the ‘checkIfPieceClicked’ function. Called in succession these simply switch the selected piece. The second logic clause checks whether the selected piece can legally move to the intended position. This function contains the following:
function canSelectedMoveToBlock(selectedPiece, clickedBlock, enemyPiece)
{
	var bCanMove = false;
	
	switch (selectedPiece.piece)
	{
		case PIECE_PAWN:
		
			bCanMove = canPawnMoveToBlock(selectedPiece, clickedBlock, enemyPiece);	
			
		break;
		
		case PIECE_CASTLE:
			
			// TODO
			
		break;
		
		case PIECE_ROUKE:
		
			// TODO
			
		break;
		
		case PIECE_BISHOP:

			// TODO
			
		break;
		
		case PIECE_QUEEN:
		
			// TODO
				
		break;
		
		case PIECE_KING:
		
			// TODO
			
		break;
	}

	return bCanMove;

}
The function above uses the switch statement to determine which piece is in-play. This code only deals with the pawn and the logic is within the function called ‘canSelectedMoveToBlock’:
function canPawnMoveToBlock(selectedPiece, clickedBlock, enemyPiece)
{
	var iRowToMoveTo = (currentTurn === WHITE_TEAM ? selectedPiece.row + 1:selectedPiece.row - 1),
		bAdjacentEnemy = (clickedBlock.col === selectedPiece.col - 1 ||
					clickedBlock.col === selectedPiece.col + 1) &&
					enemyPiece !== null,
		bNextRowEmpty = (clickedBlock.col === selectedPiece.col &&
					blockOccupied(clickedBlock) === false);
					
	return clickedBlock.row === iRowToMoveTo &&
			(bNextRowEmpty === true || bAdjacentEnemy === true);
}
The logic above is crude and only permits the pawn to move one block forward, or one block in a diagonal direction (if the opposing team occupies the block). This logic does omit to cater for a few of the legal moves for the pawn! Feel free to complete the logic.

Assuming the move is legal the ‘movePiece’ function will be called:
function movePiece(clickedBlock, enemyPiece)
{
	// Clear the block in the original position
	drawBlock(selectedPiece.col, selectedPiece.row);
	
	var team = (currentTurn === WHITE_TEAM ? json.white:json.black);
	var opposite = (currentTurn !== WHITE_TEAM ? json.white:json.black);

	team[selectedPiece.position].col = clickedBlock.col;
	team[selectedPiece.position].row = clickedBlock.row;
	
	if (enemyPiece !== null)
	{
		// Clear the piece your about to take
		drawBlock(enemyPiece.col, enemyPiece.row);	
		opposite[enemyPiece.position].status = TAKEN;
	}
	
	// Draw the piece in the new position
	drawPiece(selectedPiece, (currentTurn === BLACK_TEAM));				
	
	currentTurn = (currentTurn === WHITE_TEAM ? BLACK_TEAM:WHITE_TEAM);
	
	selectedPiece = null;
}
This function performs the movement of a chess piece. It first clears the current block, by calling the ‘drawBlock’ function. It then updates the piece’s properties within the data-structure. The penultimate step is to check whether the target block is occupied by the opposing team. If so, the block is cleared and the status of the opposing teams piece is updated to TAKEN. Finally the moving chess piece is drawn in the new location and the turn variable is switched.

That concludes one’s experiment with my Chess board. I hope this helps someone out there. All the code above may be taken and used for anything – credit not required. Although, it would be nice to know. A working version of this project can be viewed here. The source code for this project can be obtained from my Git Hub repository here

37 thoughts on “HTML 5 Canvas – Chess board

  1. Thanks a lot for this tutorial. I have been struggling with some of the concepts you’ve outlined here and this will be of tremendous assistance to me!

    That said, for anyone who is using this example, it should be noted that the chess squares are inverted. When playing white, the lower left-hand square (a1) should be a dark square. Because of this, the pieces are also set up incorrectly.

    Despite this easily correctable issue, this tutorial is exactly what I was looking for!

    1. Thanks for the feedback. I did ask myself the question of whether the colours were correct! And, still got it wrong 🙂 I’ll update the post at some point to correct it. Thanks again.

    1. Subash, I’ve been programmer professionally for over 15 years, so I’d say experience is a big factor. Anyone aspiring to be a programmer needs to put the hours in. I’ve worked with people who are far more skilled than me; but, we all share one common factor: passion to learn. Even today I learn new skills and more importantly want to learn more. To improve your skills get involved with one of the many open-source projects on the Internet. I’d recommend the big Linux OS project Fedora.

  2. Hi

    very nice indeed.

    just a little comment on drawing the board, you should not have to build a function to choose the color, you can instead put the colors in an array (the size of this array would be 2)
    then reverse the array every row, and choose colors[COLUMN%2]. this is much more efficent and clean. reversing array of 2 is not consuming very much proccessing power

  3. Hi Ray
    Nice post on 2 of my favourite topics chess & html5.
    Unfortunately your demo doesn’t seem to work too well for me.
    A while back I made a nice html5 dragndrop board with unicode pieces.
    Whenever I complete my own chess engine I hope to hook them up!
    I looked at your github sources and I’m not sure about sonar files-some project management thingy?
    Anyway thanks again & best wishes

    1. My intention for the Chess project was to simply prove the concept. More for my own education 🙂 One day I may revisit and finish it off.

      The sonar files are for project control. Specifically, they relate to managing source code quality. I’ve done a blog post on the benefits of using sonar if you are interested.

    1. The key to storing the board in array would be to understand the json variable. This data structure holds the game state e.g. each piece has its location and in-play-state. Storing this in a 2D array would suite your need.

      1. Again, the json data-structure is key. Each piece is represented by an object which has its row and column position. This is its position on the board.

  4. how to run this chess board in server, so that other user can play online with some other user?
    how to make rooms for this game like play,beginner,tournament,etc. and join them to a user?

      1. The algorithm for creating a computer opponent is well documented on the web. The logic would be better client side for offline play.

  5. Hi need help .. I have coded an algorithm in java that plays against human.. in my java code i have a function which returns returns possible moves(i.e returned information will be in-terms of string ) when human player clicks on any piece.my doubt is how to call this function from the html5 when human player clicks on any piece ???.. should i use jason or javascript or ajax etc.. please help i am beginner in html 5 and javascript

    1. the function i am talking about will return the information in terms of string… I will reprocess it in html5 to know which square boxs i should highlight

      1. Any call to a server should be done using AJAX or Websockets. The data returned should be formatted using JSON rather than strings.

  6. I’d like to use the chess figures you have used in your example. Can I used it or do you have a suggestion on how I can get an svg set of chess pieces for my chess application?

    1. There are lots of free site with SVG format. Normally if you need a quality set of images it’s best to obtain a paid for licensed version. I think the ones in my example are creative common license; but, I forgot where I sourced them from.

  7. thanks for your great tutorial mate. I’m trying to learn Canvas programming for a turn based wargame and I’m sure I’ll find here good hints on how to handle user interactions with pieces on a map instead than a chessboard.

  8. I’m sure this is all very cool and whatever, but doesn’t chess require a white square to be on the bottom right corner? 😉 Didn’t read the whole article, as it’s way above my head, so if it’s deliberate, my bad

Leave a reply to daixtr Cancel reply