21๐
As you discovered, canvas.toDataURL()
does not capture any visual styling applied via CSS. It only captures the raw pixel data from the bitmap backing the canvas instance. This is by design.
In order to use a custom background color, you need to draw it directly to the canvas. Here is an example of a function that fills the background of a given canvas with a given color. My inline comments should explain how it works.
function fillCanvasBackgroundWithColor(canvas, color) {
// Get the 2D drawing context from the provided canvas.
const context = canvas.getContext('2d');
// We're going to modify the context state, so it's
// good practice to save the current state first.
context.save();
// Normally when you draw on a canvas, the new drawing
// covers up any previous drawing it overlaps. This is
// because the default `globalCompositeOperation` is
// 'source-over'. By changing this to 'destination-over',
// our new drawing goes behind the existing drawing. This
// is desirable so we can fill the background, while leaving
// the chart and any other existing drawing intact.
// Learn more about `globalCompositeOperation` here:
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
context.globalCompositeOperation = 'destination-over';
// Fill in the background. We do this by drawing a rectangle
// filling the entire canvas, using the provided color.
context.fillStyle = color;
context.fillRect(0, 0, canvas.width, canvas.height);
// Restore the original context state from `context.save()`
context.restore();
}
To use the function, call it before your save code, giving it the chart canvas and a color. It should look something like this:
const canvas = document.getElementById('yourCanvasId');
fillCanvasBackgroundWithColor(canvas, 'aquamarine');
// ...the rest of your save code
The saved image should have a background color.
2๐
Iโm leaving this here, since I bumped onto an easier alternative solution that at least worked for me.
When I used chartCanvas.toDataURL("image/jpeg", 1.0);
My colors were all messed up just like the OP.
Just switching to png worked for me. No plugins or extra work. Just changing to chartCanvas.toDataURL("image/png", 1.0);
made the dataUrl output look exactly like my chart.