How to download HTML Canvas elements – toDataURL()

What happend

This article is another chapter in my journey with Chart.js, where I encountered a new challenge. As I was developing an online chart visualization, I realized the need for a download functionality. This led me to explore how to implement it.

In this article, I’ll share my experience with tackling this challenge and provide insights into how to navigate this seemingly straightforward task while working with Chart.js and its canvas-based charts.

toDataURL()

toDataURL() is a unique function exclusive to the canvas element. It returns a DataURL object representing the contents of the canvas element.

In simple terms, it generates a string containing the image format and the image itself encoded in Base64.

There are two optional parameters that can be passed: type and encoderOptions.

toDataURL()
toDataURL(type)
toDataURL(type, encoderOptions)

type: The image format, which defaults to image/png.

encoderOptions: The image quality, ranging from 0 to 1, where a higher value indicates higher clarity and a larger file size. (*Note that this parameter only affects image types with lossy compression formats, such as jpeg and webp.)

The obtained DataURL object can be used for various purposes:

  • Displaying on a webpage: You can directly use it as the source (src) for an image or an iframe element.
  • Downloading: You can offer the DataURL as a downloadable link for users to save the image locally.

Why is the downloaded/referenced image showing up as black?

Let’s take a look at a simple example:

See the Pen canvas_download_1 by story zyra (@story-zyra) on CodePen.

⬆️ You can try it by yourself.

Why is it displaying as black?

This issue is actually related to the image file type! This problem only occurs with the JPEG format.

Take a look at the example below to see for yourself. I’ve modified the download process to use an iframe for displaying:

See the Pen canvas_img_test by story zyra (@story-zyra) on CodePen.

It’s evident that PNG and WebP files don’t have this issue.

After some research, I discovered that JPEG doesn’t support transparent backgrounds. This might be the reason behind the default behavior of converting to black.

However, the solution is quite simple: draw your own background.

    var ctx = canvas.getContext('2d');

    ctx.globalCompositeOperation = 'destination-over'
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

The line “ctx.globalCompositeOperation = ‘destination-over'” allows the newly drawn background to appear underneath the existing chart.


Conclusion

In addition to online reporting, I’ve also developed some other small features. I hope to share them with everyone in the future. Currently, I’m in the process of finding the right platform for deployment.

If the opportunity arises and things go well, I’ll definitely appreciate your support when the project goes live.

🧡 Hopefully, this post has helped you to some extent.

🧡You can support me by clicking some ad, Thanks a lot

If you got any problem about the explanation, please feel free to let me know

Some Random notes

Leave a Reply

Your email address will not be published. Required fields are marked *