While surfing the web for inspiration, we bumped into the beautifully-designed Honda HR-V website. When you navigate from a section to the other, the transition is embellished by an animated shape - created using a <canvas>
element.
We decided to create something similar, but instead of using canvas, we played with SVG. Also, instead of creating a vertical layout that would require forced scrolling to see the animation, we turned the whole resource into a hero slider.
Resources used:
- Snap.svg to animate the SVG elements.
- Icons from our Nucleo library.
- Images from Unsplash.
Creating the structure
The HTML is structured in 3 main elements: an unordered list (ul.cd-slider
) containing the slides, an ordered list (ol.cd-slider-navigation
) for the slider navigation, and a div.cd-svg-cover
, used to create the animated shape visible when you switch from one slide to the next one.
<section class="cd-slider-wrapper">
<ul class="cd-slider">
<li class="visible">
<div>
<h2>Animated SVG Slider</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi, explicabo.</p>
<a href="#0" class="cd-btn">Article & Download</a>
</div>
</li>
<li>
<!-- slide content here -->
</li>
<!-- additional slides here -->
</ul> <!-- .cd-slider -->
<ol class="cd-slider-navigation">
<li class="selected"><a href="#0"><em>Item 1</em></a></li>
<li><a href="#0"><em>Item 2</em></a></li>
<li><a href="#0"><em>Item 3</em></a></li>
<li><a href="#0"><em>Item 4</em></a></li>
</ol> <!-- .cd-slider-navigation -->
<div class="cd-svg-cover" data-step1="M1402,800h-2V0.6c0-0.3,0-0.3,0-0.6h2v294V800z" data-step2="M1400,800H383L770.7,0.6c0.2-0.3,0.5-0.6,0.9-0.6H1400v294V800z" data-step3="M1400,800H0V0.6C0,0.4,0,0.3,0,0h1400v294V800z" data-step4="M615,800H0V0.6C0,0.4,0,0.3,0,0h615L393,312L615,800z" data-step5="M0,800h-2V0.6C-2,0.4-2,0.3-2,0h2v312V800z" data-step6="M-2,800h2L0,0.6C0,0.3,0,0.3,0,0l-2,0v294V800z" data-step7="M0,800h1017L629.3,0.6c-0.2-0.3-0.5-0.6-0.9-0.6L0,0l0,294L0,800z" data-step8="M0,800h1400V0.6c0-0.2,0-0.3,0-0.6L0,0l0,294L0,800z" data-step9="M785,800h615V0.6c0-0.2,0-0.3,0-0.6L785,0l222,312L785,800z" data-step10="M1400,800h2V0.6c0-0.2,0-0.3,0-0.6l-2,0v312V800z">
<svg height='100%' width="100%" preserveAspectRatio="none" viewBox="0 0 1400 800">
<title>SVG cover layer</title>
<desc>an animated layer to switch from one slide to the next one</desc>
<path id="cd-changing-path" d="M1402,800h-2V0.6c0-0.3,0-0.3,0-0.6h2v294V800z"/>
</svg>
</div> <!-- .cd-svg-cover -->
</section> <!-- .cd-slider-wrapper -->
Adding style
By default, all the slides have an opacity: 0, are in absolute position and are placed one on top of the others (top: 0 and left:0). The .visible
class is added to the selected slide to make it visible (opacity: 1).
.cd-slider-wrapper {
position: relative;
}
.cd-slider > li {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.cd-slider > li.visible {
/* selected slide */
position: relative;
z-index: 2;
opacity: 1;
}
Events handling
To animate the SVG, we animated the 'd'
attribute of the path element inside the .cd-svg-container
.
First of all, we had to define the different steps of the animation (in our case, 5 steps to animate from a slide to the next one and 5 more steps to animate from a slide to the previous one); basically we had to create 10 different svg paths elements (all with the same number of anchor points for the animation to properly work), as shown in the following screenshot taken from the Illustrator file (note that some steps seem empty, but they all contain a path).
Once the paths have been defined, we added to the .cd-svg-cover
a data-stepn
attribute (one for each step) equal to the 'd'
attribute of the defined path (to easily retrieve it with JavaScript).
We then used the animate()
method provided by Snap.svg to animate from a path to the next one:
var svgCoverLayer = $('.cd-slider-wrapper').find('div.cd-svg-cover'),
svgPath = Snap('#cd-changing-path'),
path1 = svgCoverLayer.data('step1');
svgPath.animate({'d': path2}, 300, customMinaAnimation, function(){
//...
});
The easing function is a custom cubic-bezier function; unfortunately this is something wich is not available by default in Snap.svg, but you can create a custom timing function from your custom cubic-bezier (here's a StackOverflow post that covers it in details).
Illustrator trick: for this technique to work, you need <path>
elements. In Illustrator, if you use only straight lines, a <polygon>
element is created. To convert it to a <path>
, you can add a border-radius to one of anchor points.