/* ====================== Chessboard Constructor ====================== canvasComp => your canvas id in your index.html onCompleteCallback => add your logic here, as it is executed as soon as all images have been loaded. */ var ChessBoard = function(canvasComp, onCompleteCallback){ this.canvas = canvasComp; this.canvasCtx = this.canvas.getContext("2d"); this.pictures =[ {src:"asset/wp.svg", value:null}, {src:"asset/wn.svg", value:null}, {src:"asset/wb.svg", value:null}, {src:"asset/wr.svg", value:null}, {src:"asset/wq.svg", value:null}, {src:"asset/wk.svg", value:null}, {src:"asset/bp.svg", value:null}, {src:"asset/bn.svg", value:null}, {src:"asset/bb.svg", value:null}, {src:"asset/br.svg", value:null}, {src:"asset/bq.svg", value:null}, {src:"asset/bk.svg", value:null}]; this.NO_PIECE = "X"; this.PICTURES_SIZE = 504; this.piecesValues = Array(8); // first dim is for rank, and first index is for rank "1" for (var line = 0; line < 8; line++){ this.piecesValues[line] = Array(8); } /* ============ Initializer ============ */ this.init = function(){ var minWindowSize = Math.min(window.innerWidth, window.innerHeight); this.canvas.width = minWindowSize; this.canvas.height = minWindowSize; this.cellSize = Math.floor(minWindowSize / 8); var outer = this; var loadAllPictures = function(internalOnCompleteCallback){ var loadedNumber = 0; var loadSinglePicture = function(pieceIndex){ var image = new Image(); image.src = outer.pictures[pictureIndex].src; var scaleCoeff = outer.cellSize * 1.0 / outer.PICTURES_SIZE; image.addEventListener("load", function(){ outer.pictures[pieceIndex].value = image; loadedNumber++; if (loadedNumber >= outer.pictures.length) { internalOnCompleteCallback(); onCompleteCallback(); } /* outer.canvasCtx.save(); outer.canvasCtx.translate(x,y); outer.canvasCtx.scale(scaleCoeff, scaleCoeff); outer.canvasCtx.drawImage(image, 0, 0); outer.canvasCtx.restore(); */ }); }; for (var pictureIndex = 0; pictureIndex < outer.pictures.length; pictureIndex++){ loadSinglePicture(pictureIndex); } }; loadAllPictures(function(){ outer.clearValues(); }); }; /* ============== Refresh board ============== */ this.updateBoard = function(){ var outer = this; var clearCanvas = function(){ outer.canvasCtx.clearRect ( 0 , 0 , outer.canvas.width, outer.canvas.height ); } var drawSquare = function(line, col){ var blankCell = (line+col)%2 == 0; var cellColor = blankCell ? "#CF3" : "#963"; var x = col * outer.cellSize; var y = line * outer.cellSize; outer.canvasCtx.fillStyle = cellColor; outer.canvasCtx.fillRect(x, y, outer.cellSize, outer.cellSize); } var drawGrid = function(){ for (var line = 0; line < 8; line++){ for (var col = 0; col < 8; col++){ drawSquare(line, col); } } } var drawPiece = function(kindStr, fileStr, rankStr){ var drawPicture = function(pictureIndex, x, y){ var image = outer.pictures[pictureIndex].value; var scaleCoeff = outer.cellSize * 1.0 / outer.PICTURES_SIZE; outer.canvasCtx.save(); outer.canvasCtx.translate(x,y); outer.canvasCtx.scale(scaleCoeff, scaleCoeff); outer.canvasCtx.drawImage(image, 0, 0); outer.canvasCtx.restore(); } var kindIndex = "PNBRQKpnbrqk".indexOf(kindStr); var kindExists = kindIndex >= 0 && kindStr.length > 0; var fileIndex = fileStr.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0); var rankIndex = rankStr.charCodeAt(0) - '1'.charCodeAt(0); if (kindExists){ drawPicture(kindIndex, fileIndex*outer.cellSize, (7-rankIndex)*outer.cellSize); } } var drawAllPieces = function(){ for (var rankIndex = 0; rankIndex < 8; rankIndex++){ for (var fileIndex = 0; fileIndex < 8; fileIndex++){ var pieceKind = outer.piecesValues[rankIndex][fileIndex]; var isValidPiece = "PNBRQKpnbrqk".indexOf(pieceKind) >= 0 && pieceKind.length > 0; if (isValidPiece) { drawPiece(pieceKind, "ABCDEFGH".charAt(fileIndex), "12345678".charAt(rankIndex)); } } } } clearCanvas(); drawGrid(); drawAllPieces(); } /* ============ Clears board ============ */ this.clearValues = function(){ for (var line = 0; line < 8; line++){ for (var col = 0; col < 8; col++){ this.piecesValues[line][col] = this.NO_PIECE; } } this.updateBoard(); } /* ============= Puts a piece ============= kindStr => a char in "PNBRQKpnbrqk" string (see chess FEN notation on internet). Or "_" for remove it / set cell as empty. fileStr => a char like "A", "B", ... , "H" rankStr => a char like "1", "2", ... , "8" */ this.setPieceAt = function(kindStr, fileStr, rankStr){ var kindIndex = "PNBRQKpnbrqk".indexOf(kindStr); var kindExists = kindIndex >= 0 && kindStr.length > 0; var fileIndex = fileStr.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0); var rankIndex = rankStr.charCodeAt(0) - '1'.charCodeAt(0); if (kindExists){ this.piecesValues[rankIndex][fileIndex] = kindStr; } else { this.piecesValues[rankIndex][fileIndex] = this.NO_PIECE; } this.updateBoard(); } this.init(onCompleteCallback); };