Animated SVG Image Slider

Animated SVG Image Slider

A simple, responsive carousel with animated SVG paths used as transition effects.

Nucleo icons

Sponsored by Nucleo, a free application to collect, customize and export all your icons as icon font and SVG symbols. Made by the CodyHouse folks!

Do you want to include this resource in a product offered for sale? Learn more about our Extended License

Last week we’ve been experimenting with SVG paths to animate the content of a full-page hero slider. Today we use the same technique to create a responsive carousel. This time, though, we used SVG paths to directly clip the slide images, with no need to show an intermediate layer.

Images: Unsplash

Creating the structure

The HTML structure is composed by an unordered list (ul.cd-slider), containing the slides, and two additional list elements ( ul.cd-slider-navigation and ol.cd-slider-controls) for the slider navigations.

Each list item inside the ul.cd-slider is composed by an svg containing a <clipPath> element (used to change the clipping area of the slide image) and an <image> element (whose clip-path url attribute is the <clipPath> id).

<div class="cd-slider-wrapper">
   <ul class="cd-slider" 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="M-2,800h2L0,0.6C0,0.3,0,0.3,0,0l-2,0v294V800z" data-step5="M0,800h1017L629.3,0.6c-0.2-0.3-0.5-0.6-0.9-0.6L0,0l0,294L0,800z" data-step6="M0,800h1400V0.6c0-0.2,0-0.3,0-0.6L0,0l0,294L0,800z">
      <li class="visible">
         <div class="cd-svg-wrapper">
            <svg viewBox="0 0 1400 800">
               <title>Aimated SVG</title>
               <defs>
                  <clipPath id="cd-image-1">
                     <path id="cd-changing-path-1" d="M1400,800H0V0.6C0,0.4,0,0.3,0,0h1400v294V800z"/>
                  </clipPath>
               </defs>
          
               <image height='800px' width="1400px" clip-path="url(#cd-image-1)" xlink:href="img/img-1.jpg"></image>
            </svg>
         </div> <!-- .cd-svg-wrapper -->
      </li>

      <li>
         <div class="cd-svg-wrapper">
            <svg viewBox="0 0 1400 800">
               <!-- svg content here -->
            </svg>
         </div> <!-- .cd-svg-wrapper -->
      </li>

      <!-- other list items here -->
   </ul> <!-- .cd-slider -->

   <ul class="cd-slider-navigation">
      <li><a href="#0" class="next-slide">Next</a></li>
      <li><a href="#0" class="prev-slide">Prev</a></li>
   </ul> <!-- .cd-slider-navigation -->

   <ol class="cd-slider-controls">
      <li class="selected"><a href="#0"><em>Item 1</em></a></li>
      <li><a href="#0"><em>Item 2</em></a></li>
      <!-- other list items here -->
   </ol> <!-- .cd-slider-controls -->
</div> <!-- .cd-slider-wrapper -->

Adding style

The slider structure is quite basic: all slides have an opacity: 0, are in absolute position and are placed one on top of the other (top: 0 and left:0). The .visible class is added to the selected slide (at the end of the clipping animation) to make it visible, while the .is-animating class is added to the list item during the clipping animation (z-index: 3 so that it is over the li.visible item).

Note: we had to use the Padding Hack to make the svg responsive (IE assumes svg height to be 150px if you don't explicitly define it). Basically, we set the div.cd-svg-wrapper height to 0 and its padding-bottom to 57.15% (to preserve svg proportion, in our case 800/1400), and set the svg height and width to 100%.

.cd-slider > li {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  opacity: 0;
}
.cd-slider > li.visible {
  position: relative;
  z-index: 2;
  opacity: 1;
}
.cd-slider > li.is-animating {
  z-index: 3;
  opacity: 1;
}
.cd-slider .cd-svg-wrapper {
  /* using padding Hack to fix bug on IE - svg height not properly calculated */
  height: 0;
  padding-bottom: 57.15%;
}
.cd-slider svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Events handling

To animate the slide image clipping area, we animated the 'd' attribute of the <path> element inside the <clipPath>.
First of all, we had to define the different steps of our animation: we used the same process described in the Animated SVG Hero Slider article (Events handling section); but in this case, we needed only 6 steps (3 steps to animate from a slide to the next one and 3 more steps to animate from a slide to the previous one).

Once defined the paths, we added to the .cd-slider 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 the path element.

clipPath.attr('d', path1).animate({'d': path2}, duration, firstCustomMinaAnimation, function(){
   clipPath.animate({'d': path3}, duration, secondCustomMinaAnimation, function(){
      oldSlide.removeClass('visible');
      newSlide.addClass('visible').removeClass('is-animating');
   });
});

Besides, we implemented a basic slider for the image gallery (with keyboard and touch swipe navigation, previous/next and dots navigation).

Join our newsletter

Get our monthly recap with the latest CodyHouse news