Reputation: 4318
So I have a canvas
which I want to draw multiple images onto and then layer them, so; first image would have opacity: 0.5;
image two would have opacity: 0.7
and then third being opacity: 0.3;
. My question.
Should I have multiple canvas elements on one page and then position: absolute;
them on top of each other or try something else?
Just wondering A. Performance and B. is this semantically correct? Thanks.
Upvotes: 3
Views: 1590
Reputation: 5897
With CSS you can set the position and opacity of an img, so why would you want to use the canvas tag? A: Having multiple canvases don't seem to have an effect however we are only displaying 1 image on each canvas, B Well if it provides the output you want yes, however I would just stick with one canvas.
Exmaple 1 using one canvas : https://jsfiddle.net/CanvasCode/jae7snxh/
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var image1 = new Image();
image1.src = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQRsJ_wNvd0PfISyPZ5a_QI3Dpeo0g4T5Tuk-R26JXPxfhyFxBTVQ";
var image2 = new Image();
image2.src = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQQqnYE7Xtre5W0seeFETl00OPSGoujI6xUOHr18GzB4hJE5bCIaQ";
var image3 = new Image();
image3.src = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRkg3mvI5DwGqG9AUmOEVU6bDDQgM6fT7nQKr8D7XwbQ59lxDiVlA";
context.fillStyle = "#FF0000";
context.fillRect(0,0,500,400);
// Save original state of the context settings
context.save();
context.globalAlpha = 0.8;
context.drawImage(image1, 0, 0);
context.globalAlpha = 0.3;
context.drawImage(image2, 0, 0);
context.globalAlpha = 0.5;
context.drawImage(image3, 0, 0);
context.restore();
// Restore original state of the context settings
Chrome network shows it takes 334MS
Multiple canvas example : https://jsfiddle.net/CanvasCode/jae7snxh/3/
var canvas1 = document.getElementById('canvas1');
var context1 = canvas1.getContext('2d');
var canvas2 = document.getElementById('canvas2');
var context2 = canvas2.getContext('2d');
var canvas3 = document.getElementById('canvas3');
var context3 = canvas3.getContext('2d');
var image1 = new Image();
image1.src = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQRsJ_wNvd0PfISyPZ5a_QI3Dpeo0g4T5Tuk-R26JXPxfhyFxBTVQ";
var image2 = new Image();
image2.src = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQQqnYE7Xtre5W0seeFETl00OPSGoujI6xUOHr18GzB4hJE5bCIaQ";
var image3 = new Image();
image3.src = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRkg3mvI5DwGqG9AUmOEVU6bDDQgM6fT7nQKr8D7XwbQ59lxDiVlA";
context1.globalAlpha = 0.8;
context1.drawImage(image1, 0, 0);
context2.globalAlpha = 0.3;
context2.drawImage(image2, 0, 0);
context3.globalAlpha = 0.5;
context3.drawImage(image3, 0, 0);
Chrome network shows it takes 334MS
Upvotes: 0
Reputation: 21881
You can draw the images in the same canvas.
Just change the .globalAlpha
property before drawing the image.
ctx.save();
ctx.globalAlpha = 0.8;
ctx.drawImage(image1, 0, 0);
ctx.restore();
ctx.save();
ctx.globalAlpha = 0.3;
ctx.drawImage(image2, 0, 0);
ctx.restore();
ctx.save();
ctx.globalAlpha = 0.5;
ctx.drawImage(image3, 0, 0);
ctx.restore();
//...
Upvotes: 1
Reputation: 1258
Yes, multiple canvas elements on top of each other is a good way to achieve layering. Though, of course, I'd stick with only two or three, for performance reasons, unless you know that your site will only be viewing by performant browsers/processors. If you don't mind losing the layering in the output, you could just use one hidden canvas as a cache to prepare drawing on, and then copy each layer over from that to another canvas which you display.
If you use multiple elements, you might want to place them within a div wrapper, or something similar, for better organisation. And note that canvases are transparent by default: in other words, you can see what's underneath them so long as you don't draw over what you want to see or set a background colour.
Rather than setting the CSS opacity on your canvas elements, use instead the globalAlpha javascript property on your canvas context when you are drawing; or set the alpha as a fillStyle
before any of your individual drawing function calls, like so:
var red = 255, // 100%
green = 128, // 50%
blue = 0, // 0%
alpha = 0.5; // 50%
canvasContext.fillStyle = "rgba(" + red + "," + green + "," + blue + "," + alpha + ")";
// orange at half opacity
Upvotes: 0