Build Spotify’s Colorizer Effect with JavaScript
A cleaner and more optimized implementation using the HTML Canvas API

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.

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
.
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.
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.

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.
3. Multiply and Lighten Layers
Now the part where the magic happens. We can now use multiply and lighten in globalCompositeOperation
.
Here’s what the image looks like after multiply
:

Here’s how it looks after multiply
and 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.
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.
The final result is as follows.

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!