Earlier this year, I mentioned that I was starting out with the Kohana framework. Actually, my team uses a heavily modified version of the Kohana framework as a starter for all our projects.
In addition to the Kohana base architecture, our framework had a bunch of goodies built in, like lazy-loading, a run-time Sass compiler and so on. But I digress. We had been tasked to build the website for Audi’s SG50 Time Machine campaign.
Building the website
The front-facing site itself wasn’t too complicated. And this was the first project I kick-started, i.e. clone the framework, set it up and configure it etc. And hence came the post Introduction to the Base Framework. It contains my noob explanation of MVC as well as covers how Base Framework (a modified version of Kohana) is used by front-end developers (me, actually 🤓).
The bulk of the content was on the home page itself, with some sub-pages for additional secondary information. It was going to be a (in my own words) a pseudo-single page website. There would be four sections, the introduction, a map of the event, an accompanying video and a registration form.
The navigation links would be a combination of anchor links that scrolled down to each respective position, as well as links to the aforementioned sub-pages. Probably not the best design pattern around, but, circumstances.
Introduction section
Our designers came up with the idea to have the background transform from modern day back to 1965, in line with the “back-in-time” theme. My initial idea was very simple, just two images, with the modern day version superimposed on the 1965 version, and animating the opacity to fade out. If you read my post about diamond grids, you’ll realise that my initial simple ideas don’t fly very well with designers. ¯\_(ツ)_/¯
Turns out the requirement is for the scene to gradually transition back to the past, with different buildings and details fading out one by one. Did I mention the site is supposed to be responsive? After going through the over-engineering thought process of slicing each building and positioning them absolutely, then applying the fade-out effect with animation delays… Okay, it sounds ridiculous now I put it into words. I settled on making it a background video instead.
So the key now was to optimise the *bleep* out of that video. I used a program called Handbrake, which provides some presets for web-optimisation already. After tweaking the frame-rate and some back-and-forth with the designer in terms of discernible quality issues, I managed to get the file size down to 1.1mb (I know that’s still huge, and it still makes me 😭).
One of my favourite web tutorial sites, thenewcode.com by Dudley Storey had an article on full screen background videos, which I highly suggest you read. In fact, read all you can from that site, immediate skills level-up.
Navigation
The navigation looks sinisterly simple at first glance, but from a code stand-point, it is anything but straightforward. In fact, it warranted its own blog post of more than 2000 words.
Feel free to skip to that post and experience the trials and tribulations of someone trying to comprehend the CSS box model.
Full page scrolling
Now I’m pretty opinionated about scroll-jacking. My opinion is just don’t. The design team was pretty adamant about implementing a full page scroll though. My next best option was to provide both a full-page scroll trigger but still allowing users to scroll as per normal. Civility and compromise are the keys to a lasting relationship, people.
Seriously, IMHO, designers and developers should be best of friends. I didn’t have the time or technical skill to write a full-page scroll plugin on my own so I chose to use fullPage.js by Álvaro Trigo, which had the option of keeping native scroll behaviour in addition to full page scrolling.
My designer wanted to have some sort of animation on the scroll trigger and tried to give me a GIF file of what she wanted. Me being me, I couldn’t just take the GIF and use it, like a normal person. No no no. I told her I’d make an SVG and animate it, and we wouldn’t have to worry about pixelation! She gave a look like 🙄 and told me to knock myself out.
It was a good thing the design was reasonably simple. But I’m barely an intermediate vector wrangler, so creating the vector file itself took a bit longer than I initially expected. After a couple iterations of tweaking timings and keyframes in Codepen, I got it to look presentable.
See the Pen Animated scroll-down icon by Chen Hui Jing (@huijing) on CodePen.
The scroll icon shouldn’t be displayed when the page scrolled down to the last section, so it needed to be hidden. I could handle that function just fine.
function detectScroll() {
var scrollPos = $(window).scrollTop() + $(window).height();
var scrollHeight = $(document).height();
$('#fpScroll').addClass('transparent');
clearTimeout($.data(this, 'scrollTimer'));
if (scrollHeight - scrollPos > 800) {
$.data(this, 'scrollTimer', setTimeout(function() {
$('#fpScroll').removeClass('transparent');
}, 250));
}
}
Fixed background performance
The background image was fixed to give some semi-parallax kind of effect. But I remembered reading an article about how that impacted scrolling performance. Turns out the background-attachment: fixed
triggers a paint operation during scrolling, because the browser needs to recalculate the fixed background image’s location relative to the DOM elements around it.
The solution is to make use of a pseudo-element and the will-change
property to indicate to the browser that my fixed background ought to be rendered in its own layer. I’ve linked the article below and highly recommend you read it.
Wrapping up
This was definitely not the most technically challenging project I worked on, but as with most agency projects, technical issues are usually not the major pain points. The campaign did win the agency a bunch of awards, so that’s always good. It’s also good to be constantly reminded that writing good code is only part of what contributes to a project’s success. There are many non-technical factors that play a key role as well.