Reputation: 910
I have canvas
element with background color linear gradient. I want to get clicked pixel color, but every time I got [0, 0, 0, 0]
.
Then I've tried to get color of first pixel, but no luck.. What is wrong with that code?
const canvas = document.getElementById("example");
canvas.onclick = function(event) {
const ctx = event.target.getContext("2d").getImageData(1, 1, 1, 1).data;
console.log(ctx)
}
#example {
background: linear-gradient(54deg, rgba(179, 63, 19, 1) 0%, rgba(160, 79, 44, 1) 8%, rgba(33, 238, 20, 1) 42%, rgba(35, 182, 208, 1) 61%, rgba(0, 212, 255, 1) 76%, rgba(0, 212, 255, 1) 84%, rgba(0, 212, 255, 1) 96%);
width: 500px;
height: 60px;
}
<canvas id="example"></canvas>
Upvotes: 1
Views: 2498
Reputation: 17654
in addition to the previous answer, to get the color of the clicked pixel you need to get the x
and y
of the mouse :
var canvas = document.querySelector('#example')
var ctx = canvas.getContext('2d');
var gradient = ctx.createLinearGradient(0, 0, 300, -300);
gradient.addColorStop(0, 'rgba(179, 63, 19, 1)');
gradient.addColorStop(8 / 100, 'rgba(160, 79, 44, 1)');
gradient.addColorStop(42 / 100, 'rgba(33, 238, 20, 1)');
gradient.addColorStop(61 / 100, 'rgba(35, 182, 208, 1)');
gradient.addColorStop(76 / 100, 'rgba(0, 212, 255, 1)');
gradient.addColorStop(84 / 100, 'rgba(0, 212, 255, 1)');
gradient.addColorStop(96 / 100, 'rgba(0, 212, 255, 1)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 500, 60);
let pixel = ctx.getImageData(1, 1, 1, 1).data;
canvas.onclick = function(event) {
var x = event.clientX;
var y = event.clientY;
var colors = ctx.getImageData(x, y, 1, 1).data;
console.log(colors)
}
<canvas id="example" width="500" height="60"></canvas>
Upvotes: 1
Reputation: 4106
The linear gradient is a CSS property of the canvas, it's not drawn on the underlying bitmap you manipulate via the rendering context. That bitmap is blank by default and can only be modified programmatically.
What you need to do is draw the gradient in your JS code, then you can extract the color data. Unfortunately it's a lot more finicky than CSS, but it can be done. I threw together an example, just as a proof of concept.
Read up on createLinearGradient
on MDN:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createLinearGradient
var ctx = document.querySelector('#example').getContext('2d');
var gradient = ctx.createLinearGradient(0, 0, 50, 60);
gradient.addColorStop(0, 'rgba(179, 63, 19, 1)');
gradient.addColorStop(8/100, 'rgba(160, 79, 44, 1)');
gradient.addColorStop(42/100, 'rgba(33, 238, 20, 1)');
gradient.addColorStop(61/100, 'rgba(35, 182, 208, 1)');
gradient.addColorStop(76/100, 'rgba(0, 212, 255, 1)');
gradient.addColorStop(84/100, 'rgba(0, 212, 255, 1)');
gradient.addColorStop(96/100, 'rgba(0, 212, 255, 1)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 500, 60);
let pixel = ctx.getImageData(1, 1, 1, 1).data;
console.log(pixel);
<canvas id="example" width="500" height="60"></canvas>
Important: Note that the size of the canvas is set in the width
and height
attributes of the element, and not in CSS. This is because, as I said, there is a difference between the <canvas>
element and its underlying bitmap. The attributes let you specify the size of the bitmap, and by default that's how big your canvas will be as well. If you modify the size of the canvas via CSS, the image you draw on the bitmap will be stretched to fit those dimensions, which is rarely what you want.
Upvotes: 2