codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Follow publication

Build Spotify’s Colorizer Effect with JavaScript

A cleaner and more optimized implementation using the HTML Canvas API

Anthony Teo
codeburst
Published in
4 min readAug 6, 2020

Photo by Brooks Leibee on Unsplash

If you’ve used Spotify before, you are likely familiar with the duotone effect. Essentially, this effect works by replacing the whites in a grayscale image with one color, and the blacks with another. Since this redesign was launched in 2015, it has been used on everything from playlist covers to artist images, becoming synonymous with the brand.

There have been multiple takes on recreating this effect using mix-blend-mode in CSS, the CoreImage library for iOS, and even a Canvas implementation. So, what makes this implementation different?

Well, we will be using the globalCompositeOperation feature in HTML Canvas, which will give a duotone effect with only 40 lines of code. Compared to 100+ lines of code in the other HTML Canvas implementation that manipulated every pixel, it is more efficient while making the code more readable.

Why use the Canvas API?

In my case, I planned to generate personalized images with the favorite music for each user. I wanted to export the canvas as an image, so the user can save the image to their device.

You might be able to implement this with CSS and use a library like HTML2Canvas to export it as an image. However, this involves external libraries and the documentation for that particular library states that it does not support filter or mix-blend-mode properties, which are the building blocks of the CSS duotone implementation.

The Canvas API is a means for drawing graphics via JavaScript and the HTML <canvas> element. Our purpose fits nicely within the built-in capabilities of Canvas.

We’ll be using a photo of Swedish musician Avicii. Source: Wikipedia

1. Set up Canvas API

To start, we’ll need to set up the <canvas> element and import the image. This is done by placing the <canvas> tag in the <body> of your HTML file and assigning it an id .

Setting up the canvas element in HTML

Then, we want to import the image to draw it onto the canvas with scripts.js. We get the canvas with getElementById and start drawing with getContext as soon as the image loads.

Code to get the canvas element and draw the image on load.

2. Convert image to grayscale

This is done by getting the RGB values of each pixel and averaging them so that each channel has the same value. The modified image data is then put back into the canvas.

Code to manipulate the pixel data
Image converted to grayscale

Alternative

The Canvas API has a filter function that will do all of that work in one line of code. Unfortunately, this function is not supported in Safari, Internet Explorer, or Opera. So, pixel manipulation is still the better choice.

Using the filter() function in Canvas API

3. Multiply and Lighten Layers

Now the part where the magic happens. We can now use multiply and lighten in globalCompositeOperation.

Code to add the multiply and lighten layers

Here’s what the image looks like after multiply:

Grayscale + Multiply

Here’s how it looks after multiply and lighten:

Grayscale + Multiply + Lighten

4. Save as an Image

To save this as an image, I used the built-in toDataURL function to convert the canvas to a PNG image. Then, I assigned it to the src of an <img> tag on the page. This meant that desktop users can right-click to save while mobile users can also save the image by long pressing on it.

Function that converts canvas to an image

In addition to an image of a user’s favorite artist, I also wanted to display some other information on that image. This can be done with the fillText and fillRect functions.

Drawing text and shapes on top of the image.

The final result is as follows.

Final Image

Conclusion

So, that’s how you can recreate the duotone effect with JavaScript and only 40 lines of code. You can try various color combinations for this effect. I find that a bright color for multiply and a darker one for lighten works well. Thanks for reading!

Resources

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Written by Anthony Teo

Software engineer interested in human-centered interfaces and the digital experience.

No responses yet

Write a response