Flexslider Slides while Ken Burns

Flexslider Slides while Ken Burns

Blog Categories: 
 | Digital Frontiers Media

A client of mine recently asked me to add the "Ken Burns" pan-and-zoom effect to the slideshow that was already built on their Drupal site using Flexslider.  I didn't want to rebuild it using a different slideshow library that supported the effect out of the box and I wanted something that would produce a nice set of pans and zooms and durations that would be random and different each time the slides were presented without going beyond the slide bounds or leaving gaps or whitespace.  I came up with this javascript client-side Drupal behavior that could be added directy to the theme to add the new effect without changing anything else about the build.

It should be pretty much drop-and-go for you if you use Flexslider on your Drupal site and know how to had Drupal javascript behaviors to your theme.  It assumes the container for your slideshow uses the class "slides" as it uses jquery to target the individual slide list items with ".slides li".  To customize it, you can change the value of the following variables:

  1. effectIntensity - enter as percent, e.g. 30 = 30%
  2. minEffectDuration - enter as seconds, e.g. 5 = 5 seconds
  3. maxEffectDuration - enter as seconds, e.g. 10 = 10 seconds

The example code below defaults to a 30% effectIntensity and an effect duration of 5-10 seconds (my flexslider slide duration was 10 seconds so I set the values within these bounds).

You can see an example of this code running on the home page slideshow at https://www.robrady.com .

I hope you find it useful for adding a little extra dynamic to your static image slideshows!

Code follows:

  Drupal.behaviors.flexsliderKenBurns = {
    attach: function (context, settings) {
      var $div = $(".slides li");
      var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
          if (mutation.attributeName === "class") {
            var attributeValue = $(mutation.target).prop(mutation.attributeName);
            if (attributeValue == 'flex-active-slide') {
              var effectIntensity = 30; // enter as percent, e.g. 30 = 30%;
              var minEffectDuration = 5; // enter as seconds, e.g. 5 = 5 seconds;
              var maxEffectDuration = 10; // enter as seconds, e.g. 10 = 10 seconds;
              var slideScale = (Math.random() * effectIntensity/100) + 1;
              var slideScaleRel = (slideScale - 1) / 4;
              $(mutation.target).find('img').css({
                  transitionDuration:  (Math.random() * (maxEffectDuration - minEffectDuration) * 1000) + (minEffectDuration * 1000) + 'ms',
                  transform: 'scale3d(' + slideScale + ', ' + slideScale + ', 1) translate3d(' + $(mutation.target).width() * slideScaleRel * (((Math.random() > 0.5) * -2) + 1) + 'px, ' + $(mutation.target).height() * slideScaleRel * (((Math.random() > 0.5) * -2) + 1) + 'px, 0px)'
              });
            }
          }
        });
      });
      $div.each(function() {
        $this = $(this);
        observer.observe($this[0], {
          attributes: true
        });
      });
    }
  };