I've googled and googled about this, and all I can find, including on StackOverflow, is "support was and is broken in most major browsers." Not an actual solution to my problem.
This month's Playboy came with a pair of 3D glasses (red/cyan) to view the eye-popping centerfold. Naturally, I hit the Internets to find every single red/cyan anaglyph I could and look at how awesome they are. Eventually I found some animated GIFs, which led to the idea that maybe I should make some cool HTML5 Canvas thing that lets you put shapes on a scene in 3D.
This is how far I got. Only works well in Google Chrome. In Firefox, the "Elevated Text" should look correct, but not the rectangles.
The way I'm generating the scene is thus: There are layers that each contain a Z-index, and you can place a rectangle or some text on whichever layer you want. The concept is simple. When drawing the object, it draws one [Z-index] pixels to the left in pure red, then it draws one [Z-index] pixels to the right in pure cyan.
In theory, the overlapping parts should subtract to bee pure black. In Chrome, this happens for filling rectangles, stroking text, but not for filling text. In Firefox, this only happens for stroking text.
Although the intended effect of globalCompositeOperation="darker"
should do exactly what I want, it's obvious that going down this road is going to bring nothing but pain.
Does anyone here have an idea as to how I can get the effect I want without using globalCompositeOperation
? I tried messing with the alpha channel on the colors but didn't really like how that came together (they never add up to pure black). I could draw a third black rectangle between the red and cyan ones, but that doesn't solve the problem for text or arbitrary shapes.
I could do the pixel-for-pixel rendering myself in the Javascript, but that just seems like overkill. Any thoughts?
I've googled and googled about this, and all I can find, including on StackOverflow, is "support was and is broken in most major browsers." Not an actual solution to my problem.
This month's Playboy came with a pair of 3D glasses (red/cyan) to view the eye-popping centerfold. Naturally, I hit the Internets to find every single red/cyan anaglyph I could and look at how awesome they are. Eventually I found some animated GIFs, which led to the idea that maybe I should make some cool HTML5 Canvas thing that lets you put shapes on a scene in 3D.
This is how far I got. Only works well in Google Chrome. In Firefox, the "Elevated Text" should look correct, but not the rectangles.
The way I'm generating the scene is thus: There are layers that each contain a Z-index, and you can place a rectangle or some text on whichever layer you want. The concept is simple. When drawing the object, it draws one [Z-index] pixels to the left in pure red, then it draws one [Z-index] pixels to the right in pure cyan.
In theory, the overlapping parts should subtract to bee pure black. In Chrome, this happens for filling rectangles, stroking text, but not for filling text. In Firefox, this only happens for stroking text.
Although the intended effect of globalCompositeOperation="darker"
should do exactly what I want, it's obvious that going down this road is going to bring nothing but pain.
Does anyone here have an idea as to how I can get the effect I want without using globalCompositeOperation
? I tried messing with the alpha channel on the colors but didn't really like how that came together (they never add up to pure black). I could draw a third black rectangle between the red and cyan ones, but that doesn't solve the problem for text or arbitrary shapes.
I could do the pixel-for-pixel rendering myself in the Javascript, but that just seems like overkill. Any thoughts?
If you still need this, I have written a free context-blender library that lets you perform Photoshop-style blend modes between two canvases. I have not yet added 'darker', but you could either:
It seems that the correct mode in Firefox is globalCompositeOperation="difference". Haven't tested in Chrome or IE.
Because "difference" is a mathematical operation, there is no ambiguity in the implementation, unlike the subjective term "darker".
Maybe you would like to use darken
instead of darker
. darker
has been removed from the specification in 2007
It's a bit of a hacky way but it worked for me. You can invert the entire canvas by doing
ctx.globalCompositeOperation = "difference";
ctx.fillStyle = "white";
ctx.fillRect(0,0,canvas.width,canvas.height);
Then render whatever you want to render using globalCompositeOperation = "lighter"
. Then invert the entire canvas again and it should give the same results as a "darker" blend mode would.
I tested the suggestion of Jespertheend, and it works well. The code is bellow :
// Simulate the non existing mand :
// ctx.globalCompositeOperation = "darker";
// Draw with the plementary color,
// Draw with the plementary color, and with "lignter"
// Draw the whole rectangle with "difference"
// to obtain the equivalent of "darker"
ctx.globalCompositeOperation = "source-over"; // Default
ctx.fillStyle = "rgb(255, 0, 0)"; // opposé du cyan
ctx.fillRect(100, 20, 75, 50);
ctx.globalCompositeOperation = "lighter";
ctx.fillStyle = "rgb(0,255,0)"; // opposé du magenta
ctx.fillRect(120, 50, 75, 50);
// To invert the colors
ctx.globalCompositeOperation = "difference"; // Non standard
ctx.fillStyle = "rgb(255,255,255)"; // == @ffffcc
ctx.fillRect(100, 20, 95, 80);