Build a website in ten minutes. Cut and paste. Template-driven.
Whether they initially realize it or not, these terms and solutions aren’t a fit for our clients. Instead, every promotion site we develop must adhere to a client’s creative standards, style, and voice.
When Bose asked us to develop Sound Sanctuary – a site to share how Bose products help a friend or family member cope or heal – they requested we include a full-bleed, dynamically looping background-image gallery in the website’s header area.
What’s particularly special about this header can be broken down in three parts:
- Complex content that needs to sit above the dynamically looping images
- A background area with adjustable opacity, based on the displayed image
- Providing functionality that allows the visitor to change the index of the looping images in real-time
Dealing with opacity
Those who have dealt with the opacity requirement are aware of the technical considerations needed when placing content on layers that need to utilize opacity. At its surface the answer seems simple – set the background
property of our header element to an image and set the opacity
property to something a bit translucent like 0.8
. Even when considering a looping set of background images, this answer seems ok because they can be set programmatically – so it’s not the looping that causes an issue.
The problem with this approach is that setting the opacity
property on an element affects all children elements. Because we need to adjust the opacity and place complex layout content in child elements (really this background is just one layer of multiple in an intricate header), this solution won’t work for us.
Instead, we utilized a solution we’ve deployed many times in the past – creating a separate sibling element that sits alongside our parent element, but doesn’t have any children elements of its own.
To allow this to work we need to set the sibling’s position
property to absolute
, and give it a width
and height
of 100%
. Then, we give our main parent element a position
property of relative
and make sure to have its height set.
Now we are free to set the opacity
of our sibling element and dynamically set the background
images without intruding on our child elements.
Creating the looping image gallery
Let’s look at how we coded the looping gallery and animation alongside the dynamic image selection.
Programmatically, we needed to not only allow the background images to loop on their own timer, but we also need to account for the fact that users may change the background image at any time by clicking on the small indicators at the bottom of the header.
To achieve this, we decided to start the background-looping action on a timer using the browser’s setInterval
function. This looping action would consist of:
- Lowering the
opacity
- Removing the current image
- Placing the new image
- Increasing the
opacity
Typically, this coding is sufficient. However, since users can interrupt and alter the background-looping action, we needed make further maneuvers.
Using setInterval()
First, we store the result of the setInterval
browser function in a variable in our Vue
instance. setInterval
is a way to kick-off a function repeatedly on a set time – perfect for our use-case. setInterval
returns the id
of its instance, which gives us a hook into the process. This is important because there’s actually no way to poll the browser for all active intervals – we need to keep track of them.
Then, whenever a user chooses a new background image, we cancel the old setInterval
and set a new setInterval
instance based on the background image the user selected. The user will see their selected image appear, then the looping will proceed normally, displaying the next image in the array . Using this process we programmatically bob-and-weave as a user changes the background image and restarts the looping dynamically. BUT, we’re still not done!
Implementing the fading transition
Just like their products, Bose’s brand reflects a premium, solidly-engineered feel. We wanted to bring that same luxurious quality to the fading transition animation between the looping background images.
Visually, we landed on a transition
value of opacity 1.4s ease-in-out
– moving slowly in and out of each image to add a premium feel to the animation.
Also, you may have noticed we are only transitioning
the opacity
property – this is very important because only a few select properties are considered safe to transition without completely bogging down one’s browser. The other safe properties are position
, scale
, and rotation
. If you’d like, check out this article by Paul Lewis and Paul Irish to read more on why this approach is important for performance.
Wrapping up
We hope you found a little insight into the process of crafting just a single site component to be useful. Why not check out the live site to see it in action? And, if you’re ready to begin crafting your next unique motivational marketing website, give us a call at 781-639-1937 or drop us a note.
Contributing Author
John Datserakis
Lead Full Stack Developer