Color Thief is really neat; it can scan an image and tell you a couple of things about it:
- Its representative color palette
- Its most dominant color
We used Color Thief in a recent project to scan multiple images and, for each one:
- determine its dominant color
- use that dominant color as the background color behind the image
- set the image to 50% opaque
…the result being an image that appears to be tinted to its dominant color. Here’s the difference; the first image is before tint and the second one is after:
That looks nice, doesn’t it? You can see many more of them on the project’s Discover page.
There’s Always a but
…but there was one scenario where the tint effect resulted in a lousy experience: bright images. The design called for a few elements to sit on top of the image—some of which are bright themselves—so we needed to be sure that the image's tint is always dark enough to support the legibility of whatever might be on top of it. Here’s one of the problematic images:
It’s difficult to see the text and the gold icons, and that’s just not cool. To improve the legibility of these brighter images, we figured we had two options:
- change the color of the text and icons to something much darker, or
- rather than tint the image to its dominant color, tint it with black instead.
For consistency’s sake we decided to go with the second option, then had to figure out how to pull it off—how to programmatically say, You know what? This image is too bright, so rather than tint it to its own dominant color, I’d like to tint it with black.
We ended up utilizing the handy every() method, which tests whether all elements in an array pass a test implemented by a provided function. Since Color Thief gives us the image’s dominant color in an array of red, green, and blue values, we used every()
to test whether or not all of them were equal to or greater than a number that we felt meant the image was bright—bright enough to warrant a black tint.
The number we chose is 190, which was the sweet-spot for our needs. If all three values in the array are 190 or above, we add a class of bright-photo
to the image’s parent element.
Over in the stylesheet there’s a selector that sets a black background color on any element with a class of bright-photo
and, with all of this in place, the result is much more legible; compare the image above with this one:
Here’s the code that handles all of the logic described above; read its comments to see how and when certain things are happening, and don’t hesitate to get in touch with us if you have any comments, questions, etc.
// Any image we want to use Color Thief on is given the class 'color-thief'.
var target_images = $('.color-thief');
var color_thief = new ColorThief();
// For each image...
$(target_images).each(function() {
// Use Color Thief to get its dominant color, then change it from an array to
// a comma-separated string for use later.
var dominant_color = color_thief.getColor(this);
var dominant_rgb = dominant_color[0] + ',' + dominant_color[1] + ',' + dominant_color[2];
// Make the image semi-transparent, then travel up (2) parents, then set that
// element's background-color to the red, green, and blue values obtained above.
$(this).css('opacity', .5).parent().parent().css({'background-color': 'rgb(' + dominant_rgb + ')'})
// If the dominant color is found to be somewhat bright by using the is_bright
// function below, travel up (2) parents and add a class of 'bright-photo',
// with which we make some adjustments over in the CSS.
if (dominant_color.every(is_bright)) {
$(this).parent().parent().addClass('bright-photo');
}
});
// If each value in an array is equal to or above 190, return true.
function is_bright(element, index, array) {
return element >= 190;
}
Thanks for reading!