I am working on a relatively simple app that will generate differently colored version of the same .SVG image (modified by HSL values).
Right now I'm implementing hue changes. I am using a generated list of colors. Before drawing the color variations a base color is selected. In this case I used a dead simple .SVG of a green square (hsl(137,100%,82%)
).
This is what my code looks like:
for(let i = 0; i < nColors; i++){
ctx.filter = 'hue-rotate('+(palette[i].h-hStart)+'deg)';
ctx.drawImage(img, i*100, 0, 100, 100);
ctx.filter = "none";
}
where:
nColors
is the amount of colors in the arraypalette
is an array of objects with propertiesh
,s
andl
- cointains the colorshStart
is the base hue of my image (in this case 137)
I'm calculating the hue difference between the current color and the base color and rotating the canvas drawing hue by that number, then drawing the squares side by side. Unfortunately, here are my results.
The list at the top contains the actual colors I want to impose on my .SVG, the squares at the bottom are my canvas.
As you can see, the color diverts more and more with each iteration. I've checked the exact colors in Photoshop (I know Photoshop uses HSB but I converted the values) and the S&L differences are really big and somewhat regular (the first one is correct).
- 100,82
- 100,82
- 100,89
- 83,100
- 52,100
- 53,100
- 60,100
- 62,100
Now, I did read somewhere that different browsers may render colors differently so I checked the colors with getPixelData and the results matched my Photoshop readings, therefore I believe that the issue indeed lies in the hue-rotate filter.
I could achieve the same results by reading all the pixel data and changing it "manually", but in the end I'd like to paint each new image to an invisible, large canvas and export high resolution .PNGs - it would be rather CPU intensive and take a long time.
Is it actually a bug/feature of hue-rotate or am I making a mistake somewhere? Is there any way to fix it? Is there any other way to achieve the same results while keeping it relatively simple and sticking to vectors?
EDIT: here's a fiddle