Saturday 29 March 2014

Filled Under:

Recreating Medium’s Parallax Blur Effect

10:07:00


Recently I’ve been spending a little (probably too much) time over on Medium, reading a few interesting stories throughout the day to help give me a break from day-to-day work. I’m not a huge fan of everything that’s posted (as a lot of it is over opinionated banter), so I tend to read posts that aren’t web design/development related to help give my mind a refresh.
However I am a huge fan of the website’s design, simplicity, user-experience and attention to detail. It’s a beautifully crafted website, with some really nice, simple effects.
If you’re not familiar with Medium, it’s a community contribution based blogging system, founded by Evan Williams (the co-founder of Blogger and Twitter). However, I’m not going to bore you what I think about it, as that’s not the point of this article.

Recently, I’ve noticed a lot of posts that have a parallax blur effect – see this as an example. As you scroll down and the image comes into viewport, it smoothly transitions into a blur, which you can then add a text overlay to if you like. Although simple, it’s a really beautiful effect that can make a a big impact.
I don’t write on Medium myself so I wasn’t sure what was going on in terms of if the image is blurred using jQuery or not. After inspecting the code I noticed there are two images – a regular version and a blurred version. So I’m guessing that the user uploads the regular one and Medium auto-generates a gaussian blurred version for the parallax.
It’s quite simple really, both images are layered over the top of each other, and as you scroll the blurred version becomes visible, giving the impression that it’s being progressively blurred as you scroll.
In this experiment, I’ll be recreating the effect using some really simple jQuery. Here’s a bit of info on how I did it as well as a demo for you to pick apart.

The HTML

<div class="image-wrap">
<div class="regular" style="background:url(images/photo1.jpg) no-repeat center center; background-size: cover;"></div>
<div class="blurred" style="background:url(images/photo1-blurred.jpg) no-repeat center center; background-size: cover;"></div>
</div>

As you can see, the HTML is real simple. We wrap 2 divs (with background image attributes – a blurred and a regular version) in a wrapper div. To blur the image, I opened it in Photoshop and applied a gaussian blur of about 20.

The CSS

/* Blur Effect */
.image-wrap {
position:relative;
height:600px;
overflow:hidden
}
.regular, .blurred {
position:absolute;
width:100%;
min-height: 600px;

-webkit-transform: translate3d(0,0,0);
}
.regular {opacity:1;}
.blurred { opacity:0;}

The CSS is equally minimalist. Set the wrapper to position:relative and the inner images to position:absolute to stack them ontop of each other. The most important thing here is the “-webkit-transform: translate3d(0,0,0);” . The reason this is here is to force hardware acceleration on Chrome, which ensures that the effect is smooth. If you don’t use this, it can be laggy, particularly on retina displays.

The jQuery

function fader() {
var r = $('.blurred'),
wh = $(window).height(),
dt = $(document).scrollTop(),
elView, opacity;

// Loop elements with class "blurred"
r.each(function() {
elView = wh - ($(this).offset().top - dt + 200);
if (elView > 0) { // Top of DIV above bottom of window.
opacity = 1 / (wh + $(this).height()) * elView * 2
if (opacity < 1) // Bottom of DIV below top of window.
$(this).css('opacity', opacity);
}
});
}

Ok this is where the magic happens. First we set our variables which helps in caching parts of the function. Then we create a loop function so it can be set on multiple classes. Opacity goes from 0 – 1 so we divide 1 by window height and multiply it by the pixels the blurred div is from bottom. In addition we add the height of the blurred div the window height, so that the opacity works until it is out of view (Bottom border is at top of window).
Now all that’s left is to bind the function to document scrolling:
$(document).bind('scroll', fader);

That’s it! Take a look at the demo below or download the source files for more information.


I Hope you enjoyed this experiment! Please note the effect in the header was created by Anderson Storm and can be found on GitHub here. The images are via gratisography.

0 comments:

Post a Comment