iTunes-style color schemes for WordPress
• ~900 words • 4 minute read
Today I worked on a project that called for some large images that took up the full view of the browser with a text overlay on top. It's a fairly common design pattern for websites right now — Squarespace seems to be a big proponent of this approach — and it's a nice way to make a site or page more interesting while still embracing the minimal/flat aesthetic, which is also popular right now.
If you have absolute control over the image then you'll probably choose a contrasting color for the text you're going to overlay on top of the image. If the colors and contrast in an image vary a lot you'll probably want to be particular about where you put it. Generally speaking, it's easiest to get away with this kind of approach on-top of black & white photography. For a fun example ((And a fun read! I almost wanted to write about the oddity of rewriting a real-world tragedy in a super-hero universe when it's one that many people around today actually lived through... But I'm not in college anymore.)) check out the X-Men movie promotional site The Bent Bullet.
The project I was working on had a little more variability in color-scheme and text content to consider. The lazy — but also more time-tested and possibly best — approach might be to choose a white-on-black or black-on-white box to house the text content and simply overlay that on top of the image. Or maybe I could extend the WordPress theme to allow the client to pick the color palettes for each new image/posting that shows up in this space, but my experience in this area has taught me the fewer options you can give people sometimes the fewer headaches you'll have down the road ((If for no other reason than less can go wrong and things are less likely to behave or become broken in unexpected ways)).
So instead I remember that iTunes does this thing where they generate an on-the-fly color palette based on album artwork. I assumed someone somewhere must've approximated the thing in JavaScript, and lo and behold I found two options:
Initially I was drawn to albumcolors only because there was a quick-and-dirty example on the front page of the documentation. Some copy-and-pasting later and it was working... But I wasn't crazy about it. Something about it seemed a little off. So I dove into the itunes-colors version instead, which require about 7% more effort in actually clicking through some of the files to find the included example. The results seemed better for my purposes and I was pleased to find it was based on a blog post by Panic — a local software company here in Portland that makes some wonderful products I use — so I ran with it.
The approach was to use the designated featured image for a given post as the backdrop and derive the color scheme from that. Simply getting the URL for the featured image requires two lines because WordPress drives me batty and can't decide what it wants to be:
$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'full' );
$backdrop_image_url = $thumbnail['0'];
The 'full' part is important because otherwise it will return the 150x150 thumbnail by default. If you're stretching the image to cover the full-width of the browser background you probably want to use the largest version of the image you have. We will also come back to another reason why this is important...
So now you have the URL and need to add a little in-line CSS, which probably feels a little gross but I would contend is not the worst thing in the world:
<div class='backdrop' style='background-image:url(<?php echo $backdrop_image_url ?>)'>
</div>
See? That didn't hurt so much ((I leave the CSS to you to figure out because it's going to be particular to how you've structured the rest of the page.)). Now we need some JavaScript that's going to run the aforementioned script from itunes-colors, calculate the color scheme and apply it.
But nothing is every quite that straightforward and what I quickly learned was that if you're using an image that's in the 1920x800 range or more the color-scheme calculating is going to take a noticeably long time. That's because it has to use the draw the image to the canvas element and effectively go through it pixel by pixel to calculate the scheme.
Obviously that will not do. What I ended up doing to speed-up the calculation was pull a second URL for the featured image, but at a much smaller size. Now that stupid little block looks double stupid:
$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'full' );
$backdrop_image_url = $thumbnail['0'];
$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID));
$backdrop_image_small_url = $thumbnail['0'];
Now we have the URL for the full-size image and the 150x150 thumbnail. The large one gets applied as before and the small one gets exposed to the global scope, which also probably feels kinda gross, but we're building a Wordpress theme — lipstick on pigs and all that.
<script>
var featuredBackdropImage = "<?php echo $backdrop_image_thumb_url ?>";
</script>
Later, in the jQuery-laden script that enables some other things for this particular theme, the itunes-color library is called but looks to this smaller URL instead of pulling the larger one we've already assigned to the backdrop element. The results are a nearly identical color scheme calculation ((This will vary more or less depending on the image itself, but I doubt it will every do so significantly.)) but in much less time.
Now I get to present this idea to the client before we scrap it and go with the black & white approach that's going to obviously be much better.