1. My experiences using Bootstrap 4 vs Bootstrap 3 : A review My experiences using Bootstrap 4 vs Bootstrap 3 : A review

Simple SVG Animations in WordPress and PHP

We wanted to create a visually stimulating experience for our new agency website, SearchBAR. We wanted crisp, slick graphics with subtle hints of animation to capture the user’s attention. We needed to work within our WordPress theme, so it needs to grab an SVG file from within our theme’s assets folder.

Enough talk, how did we do it? You will need a workflow using SASS, so just a heads up for that! Without it, animation in CSS can get pretty tiresome, and tricky.

There are libraries out there, like GreenSock, which handle alot of the hard work of animation, but if you want a lightweight solution or to understand how it works, read on.

Embedded SVG files into HTML via PHP

To animate the paths of an SVG file, we need to embed it into the HTML of our webpage. We cannot link to the SVG via an IMG tag, because we do not then have access to the paths via CSS. Think of SVG as an extension of XHTML : we need access to its DOM to be able to manipulate it, much like we do with HTML elements.

Open your code editor, and edit your functions.php file. We need to add this little snippet of code which we can use in our theme templates. This little function accepts the SVG file path, grabs the contents of the file using wp_remote_get (which is built into WordPress) and then returns those contents.

function print_svg($path) {
	$response = wp_remote_get( esc_url_raw( $path ) );
	echo $response['body'];
}

With this function, we can now grab our SVG’s and print them out onto the page. Like so :

print_svg( get_stylesheet_directory_uri().'/library/svg/main_logo.svg' );

And this is what we get, for example our SearchBAR logo

<svg class="searchbar_main_logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 539.99 83.96">
<defs>
<style>.mainlogo-1{fill:#ed706f;}.mainlogo-2{fill:#beb3ac;}
</style>
</defs>
<path class="mainlogo-1 mainlogo-magnifying-glass" d="M519.07,23.92A25.93, ..."></path>
<path class="mainlogo-2" d="M44.55,17.41a15,15,0,0,0-8.13,2,6.77,6.77,0,0, ..."></path>
</svg>

As you can see, we have the basics of our SVG. I have added classnames to the SVG wrapper as well as the PATH elements inside it. There is also a style tag controlling the visuals. Pretty much HTML and CSS! We can control the styles from our site’s main stylesheet now as well, overriding this embedded style tag, or just move the styles out. The important bit is that we can control everything via classes.

Creating animations using CSS

So we have our SVG embedded, lets start creating some animations! I really liked animate.css, so I grabbed a couple of these and added it to my SASS files. Many thanks to Daniel Eden for this! I only added the animations I really needed, so don’t load the entire stylesheet. Remember kids : site performance begins at home.


With that added, we can start animating! I will use the logo animation from SearchBAR as an example. The animation we have is the logo sliding up and fading in, then the magnifying glass slides in with opacity, and the finally each word in the tagline fades in. Very simple, but elegant.

Applying these animations to the SVG path elements

First, I set up some SASS variables to help us control the animations, as well as some dimensions for the logo. Because SVG is infinitely scalable, we get nice crisp graphics that can scale easily. For each of the elements I want to animate, I add a classname which I can hook onto to add my animations. Think of each SVG path as an HTML element, because it is now embedded in our document. I did all my maths with my variables, because I need to stagger each element’s animation : I want to animate each element in succession. Because animation is essentially time based, we need to calculate on a timeline, when an animation can occur.

For example, the tagline animation needs to happen only once the main logo and magnifying glass have finished animating. I add up the main logo’s animation and delay durations to get this. Then for each word in the tagline, I add on a further delay. In this way, I can control all my animations and durations easily in a single area of my code.

$main_logo_width: 300px;
$main_logo_tagline_width: 220px;
$animate_main_logo : 1500ms;
$animate_main_logo_delay : 800ms;

$animate_magnifying_glass  : 1000ms;
$animate_magnifying_glass_delay : 500ms;

$animate_tagline : 1000ms;
$animate_tagline_delay : $animate_main_logo + $animate_main_logo_delay ;


.searchbar_main_logo {
	animation-name: slideInUp;
	animation-duration: $animate_main_logo;
	animation-fill-mode: both;	
	animation-delay: $animate_main_logo_delay;
	
	width: $main_logo_width;
	margin-bottom: 10px;
}
.searchbar_main_logo_tagline {
	width: $main_logo_tagline_width;
	animation-delay: 500ms;
}

.mainlogo-magnifying-glass {
	animation-name: animateGlass;
	animation-duration: $animate_magnifying_glass;
	animation-fill-mode: both;	  
	animation-delay: $animate_magnifying_glass_delay + $animate_main_logo_delay;
}

.shape-tagline {
	animation-name: animateTagline;
	animation-duration: $animate_tagline;
	animation-fill-mode: both;
}

.tagline-1 { animation-delay: $animate_tagline_delay; }
.tagline-2 { animation-delay: $animate_tagline_delay + 500ms; }
.tagline-3 { animation-delay: $animate_tagline_delay  + 1000ms; }

For the logo, the magnifying glass and the tagline, I declare which animation I want to use, how long the animation needs to last, and how long the delay before the animation begins is. You may wonder what animation-fill-mode does, well so did I! To better explain it, here is a good article about it.

These are the animation keyframes I used for the login, which we call for each class via animation-name.

@keyframes slideInUp {
  from {
    transform: translate3d(0, 100%, 0);
    visibility: visible;
  }

  to {
    transform: translate3d(0, 0, 0);
  }
}

@keyframes animateGlass {
	from {
		fill: $purple;
		transform: translate3d(-50px, 0, 0);
	}

	to {
		fill: $peach;
		transform: translate3d(0, 0, 0);
	}
}

@keyframes animateTagline {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

Queuing animations via JavaScript

The above works well on page load, but what if we need to control when the animations start? For example, when we scroll down the page, we may want an animation to kick in.

Luckily, this is easy. We can simply add a class to an element, based on an event. And we know Javascript does events well. For SearchBAR, we animate small shapes for each section or ‘panel’ as we scroll down past the respective area. We need to know when our scroll position hits the start of the panel, so we can apply a class to the panel, which kicks off our animations.

"use strict";

var $cache = {
    body: $('body'),
    panels: $('.js-panel-animation')
};

var panels = {
    top: [],
    id: [],
    animatedCount: 0
};

// Set inital page scroll location
scrollPanels();

// Gather all our panels
getPanels();

// Update on page scroll
$(window).scroll(function () {
    scrollPanels();
});

// Update panel dimensions on page resize
$(window).resize(function () {
    panels.top = []; //empty our array
    getPanels();
});

function getPanels() {
    $cache.panels.each(function () {
        panels.top.push($(this).offset().top);
        panels.id.push($(this).attr('id'));
    });
}


function scrollPanels() {
    var scrollposition = $(window).scrollTop();

    // Animated Homepage panels
    if (panels.animatedCount <= panels.top.length) {
        for (var index = 0; index < panels.top.length; index++) {
            var $element = $('#' + panels.id[index]);					

            if (scrollposition >= panels.top[index]) {
                if (!$element.hasClass('is-animated')) {
                    $element.addClass('is-animated');
                    panels.animatedCount++;
                }
            }

            if (scrollposition <= panels.top[index]) {
                if ($element.hasClass('is-animated')) {
                    $element.removeClass('is-animated');
                    panels.animatedCount--;
                }
            }
        }
    }
}

This is some jQuery to handle window scroll, and resize events. First off, we set some variables to store information about each of the panels we want to animate. On page load, we need to gather all our panels, and their top Y positions in the window. Then we need to find out our current scroll position. We then have two window scroll and resize events, so we can update this information when we manipulate the browser window.

.is-animated {
	svg {
		animation-name: jackInTheBox;
	}
}

Now we can control when an animation is fired, just using a classname. In the example above, we add the classname to the parent container, which animates any SVG elements inside it. We use the animation name “jackInTheBox” here, but you can choose which animation you want.

Simple SVG Animations in WordPress and PHP
  1. My experiences using Bootstrap 4 vs Bootstrap 3 : A review My experiences using Bootstrap 4 vs Bootstrap 3 : A review