Languages
[Edit]
EN

JavaScript - how to draw pixel on canvas element?

7 points
Created by:
Majid-Hajibaba
402

In JavaScript, it is not possible to get direct access to a single pixel on the canvas element, but there are some tricks on how to do it. In this article, simple approaches have been presented.

Quick solution:

function drawPixel(context, x, y, color) {
	var roundedX = Math.round(x);
    var roundedY = Math.round(y);

    context.beginPath();
    context.fillStyle = color || '#000';
  	context.fillRect(roundedX, roundedY, 1, 1);
    context.fill();
}


// Usage example:

var canvas = document.querySelector('#my-canvas');
var context = canvas.getContext('2d');

drawPixel(context, 20, 10, 'red'); // x=20 y=10

 

Presented solutions in the article:

  1. drawing 1x1 px rectangle on canvas with fillRect(),
  2. drawing 1x1 px image on canvas with putImageData(),
  3. drawing multiple pixels on created image data
    (~double buffering with createImageData() and putImageData()).

Performance test (on Ryzen 9 5900x and GeForce GTX 970):

Draw single pixel on canvas performance test.
Draw single pixel on the canvas performance test.

Hint: running below examples pay attention on the time necessary to draw single pixel.

1. Drawing single pixel with fillRect() method example

This approach is useful when we want to draw single pixels on existing drawing.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>
    
    #my-canvas { border: 1px solid gray; }
    
  </style>
</head>
<body>
  <canvas id="my-canvas" width="200" height="200"></canvas>
  <script>

    var canvas = document.querySelector('#my-canvas');
    var context = canvas.getContext('2d');

    function drawPixel(x, y, color) {
      	// to decrease smoothing for numbers with decimal part
		var roundedX = Math.round(x);
        var roundedY = Math.round(y);
  
        context.beginPath();
        context.fillStyle = color || '#000';
      	context.fillRect(roundedX, roundedY, 1, 1);
        context.fill();
    }
    
    var colors = ['red', 'blue', 'orange', 'yellow', 'brown', 'green'];

    var t1 = new Date();

    for(var i = 0; i < 10000; ++i) {
      	var x = canvas.width * Math.random();
      	var y = canvas.height * Math.random();
      	var color = colors[i % colors.length];
      
    	drawPixel(x, y, color);
    }
    
    var t2 = new Date();
    var dt = t2 - t1;
    
    console.log('elapsed time = ' + dt + ' ms');

  </script>
</body>
</html>

2. putImageData method with single-pixel class example

This approach is useful when we want to draw single pixels on existing drawing.

Note: this solution has weak perfomrance.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>
    
    #my-canvas { border: 1px solid gray; }
    
  </style>
</head>
<body>
  <canvas id="my-canvas" width="200" height="200"></canvas>
  <script>

    var canvas = document.querySelector('#my-canvas');
    var context = canvas.getContext('2d');

    // to increase performance createImageData method 
    // should be executed once e.g. before drawing
    var image = context.createImageData(1, 1); // pixel image
	var data = image.data;

    function drawPixel(x, y, color) {
      	data[0] = color.r;
        data[1] = color.g;
        data[2] = color.b;
        data[3] = color.a;
      
        context.putImageData(image, x, y);
    }
    
    var colors = [
      	{r: 255, g:   0, b:   0, a: 255}, // red
      	{r:   0, g: 255, b:   0, a: 255}, // green
      	{r:   0, g:   0, b: 255, a: 255}, // blue
    ];

    var t1 = new Date();

    for(var i = 0; i < 10000; ++i) {
      	var x = canvas.width * Math.random();
      	var y = canvas.height * Math.random();
      	var color = colors[i % colors.length];
      
    	drawPixel(x, y, color);
    }
    
    var t2 = new Date();
    var dt = t2 - t1;
    
    console.log('elapsed time = ' + dt + ' ms');

  </script>
</body>
</html>

3. putImageData method with ~double buffering example

This approach is useful when we want to draw everything by own.

Note: this solution has very good perfomrance.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>
    
    #my-canvas { border: 1px solid gray; }
    
  </style>
</head>
<body>
  <canvas id="my-canvas" width="200" height="200"></canvas>
  <script>

    var canvas = document.querySelector('#my-canvas');
    var context = canvas.getContext('2d');

    // to increase performance createImageData method 
    // should be executed once e.g. before drawing
    var image = context.createImageData(canvas.width, canvas.height);
	var data = image.data;

    function drawPixel(x, y, color) {
      	var roundedX = Math.round(x);
      	var roundedY = Math.round(y);

      	var index = 4 * (canvas.width * roundedY + roundedX);

      	data[index + 0] = color.r;
        data[index + 1] = color.g;
        data[index + 2] = color.b;
        data[index + 3] = color.a;
    }

    function swapBuffer() {
    	context.putImageData(image, 0, 0);
    }

    var colors = [
      	{r: 255, g:   0, b:   0, a: 255}, // red
      	{r:   0, g: 255, b:   0, a: 255}, // green
      	{r:   0, g:   0, b: 255, a: 255}, // blue
    ];

    var t1 = new Date();

    for(var i = 0; i < 10000; ++i) {
      	var x = canvas.width * Math.random();
      	var y = canvas.height * Math.random();
      	var color = colors[i % colors.length];

    	drawPixel(x, y, color);
    }

    swapBuffer();

    var t2 = new Date();
    var dt = t2 - t1;

    console.log('elapsed time = ' + dt + ' ms');

  </script>
</body>
</html>

JavaScript - HTML5 canvas tutorial

Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join