EN
JavaScript - how to draw pixel on canvas element?
7 points
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:
xxxxxxxxxx
1
function drawPixel(context, x, y, color) {
2
var roundedX = Math.floor(x);
3
var roundedY = Math.floor(y);
4
context.fillStyle = color || '#000';
5
context.fillRect(roundedX, roundedY, 1, 1);
6
}
7
8
9
// Usage example:
10
11
var canvas = document.querySelector('#my-canvas');
12
var context = canvas.getContext('2d');
13
14
drawPixel(context, 20, 10, 'red'); // x=20 y=10
Presented solutions in the article:
- drawing 1x1 px rectangle on canvas with
fillRect()
, - drawing 1x1 px image on canvas with
putImageData()
, - drawing multiple pixels on created image data
(~double buffering withcreateImageData()
andputImageData()
).
Performance test (on Ryzen 9 5900x and GeForce GTX 970):

Hint: running the below examples pay attention on the time necessary to draw pixels.
This approach is useful when we want to draw single pixels on existing drawing.
xxxxxxxxxx
1
2
<html>
3
<head>
4
<style>
5
6
#my-canvas { border: 1px solid gray; }
7
8
</style>
9
</head>
10
<body>
11
<canvas id="my-canvas" width="200" height="200"></canvas>
12
<script>
13
14
function drawPixel(context, x, y, color) {
15
// Math.floor() method is used to decrease smoothing when numbers have decimal parts.
16
var roundedX = Math.floor(x);
17
var roundedY = Math.floor(y);
18
context.fillStyle = color || '#000';
19
context.fillRect(roundedX, roundedY, 1, 1);
20
}
21
22
23
// Usage example:
24
25
var colors = [
26
'#ff0000', // red
27
'#00ff00', // green
28
'#0000ff' // blue
29
];
30
31
var canvas = document.querySelector('#my-canvas');
32
var context = canvas.getContext('2d');
33
34
var t1 = new Date();
35
36
for(var i = 0; i < 10000; ++i) {
37
var x = canvas.width * Math.random();
38
var y = canvas.height * Math.random();
39
var color = colors[i % colors.length];
40
drawPixel(context, x, y, color);
41
}
42
43
var t2 = new Date();
44
var dt = t2 - t1;
45
46
console.log('elapsed time = ' + dt + ' ms');
47
48
</script>
49
</body>
50
</html>
This approach is useful when we want to draw single pixels on existing drawing.
Note: this solution has weak perfomrance.
xxxxxxxxxx
1
2
<html>
3
<head>
4
<style>
5
6
#my-canvas { border: 1px solid gray; }
7
8
</style>
9
</head>
10
<body>
11
<canvas id="my-canvas" width="200" height="200"></canvas>
12
<script>
13
14
function Drawer(context) {
15
// To increase performance, createImageData() method should be executed only once.
16
var image = context.createImageData(1, 1); // 1x1 px image used to draw pixel
17
this.drawPixel = function(x, y, color) {
18
var data = image.data;
19
data[0] = color.r;
20
data[1] = color.g;
21
data[2] = color.b;
22
data[3] = color.a;
23
context.putImageData(image, x, y);
24
};
25
}
26
27
28
// Usage example:
29
30
var colors = [
31
{r: 255, g: 0, b: 0, a: 255}, // red
32
{r: 0, g: 255, b: 0, a: 255}, // green
33
{r: 0, g: 0, b: 255, a: 255} // blue
34
];
35
36
var canvas = document.querySelector('#my-canvas');
37
var context = canvas.getContext('2d');
38
39
var drawer = new Drawer(context);
40
41
var t1 = new Date();
42
43
for(var i = 0; i < 10000; ++i) {
44
var x = canvas.width * Math.random();
45
var y = canvas.height * Math.random();
46
var color = colors[i % colors.length];
47
drawer.drawPixel(x, y, color);
48
}
49
50
var t2 = new Date();
51
var dt = t2 - t1;
52
53
console.log('elapsed time = ' + dt + ' ms');
54
55
</script>
56
</body>
57
</html>
This approach is useful when we want to draw everything by own.
Note: this solution has very good perfomrance.
xxxxxxxxxx
1
2
<html>
3
<head>
4
<style>
5
6
#my-canvas { border: 1px solid gray; }
7
8
</style>
9
</head>
10
<body>
11
<canvas id="my-canvas" width="200" height="200"></canvas>
12
<script>
13
14
function Drawer(context) {
15
var canvas = context.canvas;
16
// To increase performance, createImageData() method should be executed only once.
17
var image = context.createImageData(canvas.width, canvas.height);
18
this.drawPixel = function(x, y, color) {
19
var data = image.data;
20
// Math.floor() method is used to decrease smoothing when numbers have decimal parts.
21
var roundedX = Math.floor(x);
22
var roundedY = Math.floor(y);
23
var index = 4 * (canvas.width * roundedY + roundedX);
24
data[index + 0] = color.r;
25
data[index + 1] = color.g;
26
data[index + 2] = color.b;
27
data[index + 3] = color.a;
28
};
29
this.swapBuffer = function() {
30
context.putImageData(image, 0, 0);
31
};
32
}
33
34
35
// Usage example:
36
37
var colors = [
38
{r: 255, g: 0, b: 0, a: 255}, // red
39
{r: 0, g: 255, b: 0, a: 255}, // green
40
{r: 0, g: 0, b: 255, a: 255} // blue
41
];
42
43
var canvas = document.querySelector('#my-canvas');
44
var context = canvas.getContext('2d');
45
46
var drawer = new Drawer(context);
47
48
var t1 = new Date();
49
50
for(var i = 0; i < 10000; ++i) {
51
var x = canvas.width * Math.random();
52
var y = canvas.height * Math.random();
53
var color = colors[i % colors.length];
54
drawer.drawPixel(x, y, color);
55
}
56
57
drawer.swapBuffer();
58
59
var t2 = new Date();
60
var dt = t2 - t1;
61
62
console.log('elapsed time = ' + dt + ' ms');
63
64
</script>
65
</body>
66
</html>