skoumas
skoumas

Reputation: 199

HTML5 Canvas Checkered Pattern

I am trying to create a retro pixelated background painting. The x and y position of "pixels" are odd and even accordingly. This seems to work for a resolution (res variable) of 4 and then the % operator does not seem to work.

function drawPixelatedBackground()
{
    var res = 5;

    for (var x=0; x<settings.width/res;x++ )
    { 
        for (var y=0;y<settings.height/res;y++)
        {
            if ( (x%2==0) && (y%2==0) )
            {
                nx = x * (settings.width/res);
                ny = y * (settings.width/res);
                ctx.fillStyle= settings.colors.Fill;
                ctx.fillRect(nx,ny, nx+  (settings.width/res),ny+   (settings.height/res) );
            }

        }
    }
}

Upvotes: 4

Views: 5710

Answers (3)

Manik
Manik

Reputation: 595

To alternate color the squares we can use the fact that the diagonal squares at say (1,1), (2,2), (3,3),... will be of the same color say white and (1,2), (2,3), (3,4),... will be of the same color say black. We notice a pattern here that in (col, row) if col and row both are even or both are odd then squares have the same color(white) otherwise they have other color(black).

code logic:

if ((i % 2 == 0 && j % 2 == 0) || (i % 2 != 0 && j % 2 != 0)){
    square is white/color1
}
else{
    square is black/color2
}                   
     

const board = document.getElementById("board")
const ctx = board.getContext("2d")

let cols = 8 
let rows = 8
let squareSize = 50

function drawCheckeredBoard(ctx, squareSize, rows, cols) {
    let whiteSquareColor = "#ffe6cc"
    let blackSquareColor = "#cc6600"

    for (let j = 0; j < rows; j++)
        for (let i = 0; i < cols; i++) {
            if ((i % 2 == 0 && j % 2 == 0) || (i % 2 != 0 && j % 2 != 0)) 
                ctx.fillStyle = whiteSquareColor
            else ctx.fillStyle = blackSquareColor
            ctx.fillRect(i * squareSize, j * squareSize, squareSize, squareSize)
        }
}

drawCheckeredBoard(ctx, squareSize, rows, cols)
<canvas id="board" width="400" height="400">

Upvotes: 1

Raphael Rafatpanah
Raphael Rafatpanah

Reputation: 19967

Loop through the rows and columns like so:

for (let column = 0; column < board.columns; column++) {
  for (let row = 0; row < board.rows; row++) {

  }
}

and create the checkered pattern by drawing a rectangle if either of the following conditions is true:

  • row is even and the column is odd
  • row is odd and the column is even

In code:

if (row % 2 === 0 && column % 2 === 1 || row % 2 === 1 && column % 2 === 0) {
  canvas.context.rect(
    column * column_width,
    row * row_height,
    column_width,
    row_height
  );
}

const canvas = {
  element: document.querySelector("canvas"),
  context: document.querySelector("canvas").getContext('2d')
}

const board = {
  rows: 15,
  columns: 17,
  colors: {
    light: '#a3cf53',
    dark: '#abd55a'
  }
}

canvas.context.beginPath();
canvas.context.fillStyle = board.colors.dark;
canvas.context.rect(0, 0, canvas.element.width, canvas.element.height);
canvas.context.fill();

canvas.context.beginPath();
canvas.context.fillStyle = board.colors.light;
for (let column = 0; column < board.columns; column++) {
  for (let row = 0; row < board.rows; row++) {
    if (row % 2 === 0 && column % 2 === 1 || row % 2 === 1 && column % 2 === 0) {
      canvas.context.rect(
        column * canvas.element.width / board.columns,
        row * canvas.element.height / board.rows,
        canvas.element.width / board.columns,
        canvas.element.height / board.rows
      );
    }
  }
}
canvas.context.fill();
body {
  margin: 0;
}
<canvas width="595" height="525"></canvas>

Upvotes: 4

user2570380
user2570380

Reputation:

Little issue with your logic. I'll explain mine below.

http://jsfiddle.net/2eee9moq/2/

function drawCheckeredBackground(can, nRow, nCol) {
    var ctx = can.getContext("2d");
    var w = can.width;
    var h = can.height;

    nRow = nRow || 8;    // default number of rows
    nCol = nCol || 8;    // default number of columns

    w /= nCol;            // width of a block
    h /= nRow;            // height of a block

    for (var i = 0; i < nRow; ++i) {
        for (var j = 0, col = nCol / 2; j < col; ++j) {
            ctx.rect(2 * j * w + (i % 2 ? 0 : w), i * h, w, h);
        }
    }

    ctx.fill();
}

var canvas = document.getElementById("canvas");

drawCheckeredBackground(canvas);
<canvas id="canvas" width="300" height="300"></canvas>

  • The nested for loop draws the blocks in one row.
    • 2 * j * w + (i % 2 ? 0 : w) is shifting the x co-ordinate of each block every other row.

Upvotes: 5

Related Questions