Color scales depending on how often the point is obtained (JS Canvas)
Recently, I have created a project involving a lot of dots on the canvas to build a strange attractor. The details of this project are not very relevant, but if you want to see it in action, go here: How can I check if the attractor is strange?
The problem I am facing is this: how can I draw a point on the canvas whose color depends on the color that was already there? In other words: How to implement a color scale that depends on the number of times a certain point has been colored?
I actually found a way, but I'm not sure if it's the best one. This is how it works:
ctx.globalCompositeOperation = "lighter";
ctx.fillStyle = "rgb(50,5,1)";
ctx.fillRect(x,y,size,size);
It just adds to a color that already exists. This already looks pretty good:
But there are many limitations when using this method:
- I cannot get color from green to red like
- This method cannot be used on a white background.
- I cannot create a color scale that includes more than "fixed points" like red-> green-> blue
You may know methods that work better than mine ...
source to share
I think you need to track hits per pixel in order to implement a feature that will allow you to change the color of an image, not just luminosity or redness. As suggested above, you should use a multidimensional array to track hits per pixel.
var canvasPixels = [];
for (var y = 0; y < 1000; y++) {
canvasPixels[y] = [];
for (var x = 0; x < 1000; x++) {
canvasPixels[y][x] = 0;
}
}
There are many things you can do if you apply color math yourself. Here I am using a blue color wave.
function getColor(hits) {
var frequency = 0.3;
var r = Math.round(Math.sin(frequency*hits + 0) * 127 + 128);
var g = Math.round(Math.sin(frequency*hits + 2) * 127 + 128);
var b = Math.round(Math.sin(frequency*hits + 4) * 127 + 128);
return "rgb(" + r + "," + g + "," + b + ")";
}
Then you simply use this function while drawing to cycle through the rainbow.
canvasPixels[y][x]++;
ctx.fillStyle = getColor(canvasPixels[y][x]);
ctx.fillRect(x,y,size,size);
source to share