© Alex Libby  2018
Alex LibbyBeginning SVGhttps://doi.org/10.1007/978-1-4842-3760-1_6

6. Animating Content

Alex Libby1 
(1)
Rugby, Warwickshire, UK
 

I don’t know about you, but I’m partial to a nice glass of wine – a nice rounded glass of red goes down a treat, after a long day of developing code. It’s a good excuse to kick back, relax, and dream of making lots of money – or at least I hope so! But I digress. At this point, I suspect you’re wondering what wine might have to animating content (and in particular, SVG graphics), but bear with me on this – let me reveal all.

Take a look at https://fournier-pere-fils.com  – it’s a website for a wine producer, based in the Sancerre region of France. The site may take a few minutes to complete loading, but it is worth the wait! When it has loaded, it shows some great effects: just imagine – sun shimmering through the leaves of the tree, early dawn mist, and not a soul in sight. In fact, the only things we can see are two birds flying – and there lies the source of my inspiration for my next demo…

Animating with CSS

A closer look at the code behind the website for Fournier Père et Fils shows that the birds are part of a 10-second video clip. Although I’m never quite sure about the virtues of using video as a background, this site pulls off the effect very well: it’s kept deliberately short, so loading times are not excessive.

But – what if we could use SVG to animate part of that image, such as the birds? Well, one kind soul has already tried this out for us; take a look at https://codepen.io/matchboxhero/pen/RLebOY . This design by Steven Roberts, a developer based in the United Kingdom, shows it is possible – he’s used a suitably sourced background image, and animates the birds over the top, using standard CSS animation.

I’ve created my own version of his example, using a different image (taken from https://unsplash.com/photos/lVDnLUACI18 ) – the CSS has been cleaned up and simplified (two birds, instead of his four), but otherwise shows a great effect that we can use in future projects. Let’s take a look at it in more detail:

ANIMATING WITH CSS

For this next exercise, we’ll break with tradition and perform a review of the code – for this, go ahead and extract a copy of the animatecss folder from the code download that accompanies this book. Save the folder to our project area; let’s take a look at that code in more detail:
  1. 1.

    The markup in animatecss.html is a simple affair: we have a <div> that acts as our container, inside which we have two individual bird containers <div>s. Inside each bird-container <div>, we have an individual bird <div> – these are for the birds; this arrangement allows us to animate them across the screen and move their wings as they are flying.

     
  2. 2.

    Next, let’s take a look at the style sheet – we have a whole bunch of style classes, but the ones of interest to us are the ones beginning with bird-* or bc-*, along with the three fly-* keyframe animations.

     
  3. 3.

    We place our bird onto the background – if you take a look at the SVG, you will see that we have 10 frames within it. Once we’ve worked out what size we want our frame to be, we use this to calculate the position of the next frame in our demo.

     
  4. 4.

    The animations are managed in two different places – we control the flapping wings with the fly-cycle keyframe animation; we use the animation-timing-function to step through each frame, much like flicking through the pages of a notebook.

     
  5. 5.

    On its own the fly-cycle animation isn’t enough – to move the birds across the screen, we implement the fly-right-one and fly-right-two keyframe animations. The timings and delays are such that it gives the effect of the birds meandering across the screen, as shown in Figure 6-1.

     
../images/461821_1_En_6_Chapter/461821_1_En_6_Fig1_HTML.jpg
Figure 6-1

Our finished version of flying birds demo

Although our demo appears to require a fair amount of code, much of it follows standard CSS animation principles – if you’ve spent any time animating content with CSS, then many of these principles should not be totally unfamiliar – we’ve applied two animations using named keyframes and set appropriate duration, delay, and timing counts.

Looking at the bigger picture though, CSS animation has indeed improved immensely over the last few years; it is fast reaching a stage where it will start to really challenge JavaScript for animation. That said, it still has some weaknesses – for example, it can’t animate attributes such as <span>; this requires JavaScript. This clearly will have an impact on how we animate content, so with this in mind, let’s take a look to see what this means in practice.

Understanding the Different Methods

Where possible, I always prefer to work with CSS when animating content – there are some clear benefits to using this approach, particularly when working with SVG:
  • If you like the syntax of CSS, and most of your design work uses it, then it makes sense to use it for animation;

  • Your project uses inline SVG, and you only need it to animate basic properties, such as fills or strokes;

  • You want to make use of browser optimizations when working with CSS animation.

Sometimes though we might have to resort to using a JavaScript-based solution – this is particularly true if our project is fairly complex, we need to use more heavyweight tools, and we don’t want to have to worry about matching timings for multiple elements.

If we must resort to using JavaScript, then what does this mean for us? Well, we have a few routes we can take (although it’s likely we may use a mix of all three in reality):
  • <animate> - SVG has its own built-in animate tag; this means we can keep our animation within the SVG and do not have to rely on third-party libraries to manage animation;

  • Plain JavaScript – most properties can be referenced using standard JavaScript syntax;

  • jQuery or third-party library – this route opens up a host of opportunities for us, such as using the likes of jQuery or the popular Snap.svg library. This places an additional overhead in terms of importing the library but will often remove some of the manual grunt required in creating the animation.

So – we have a few options available to us; which should we use? Clearly this will depend on the nature of our requirements (I feel “how long is a piece of string?” or “what are you trying to achieve?” questions coming at this point!). To get a flavor of what is available, we’ll run through using examples of each route throughout the course of this chapter – we’ll begin with a look at transforming content using the CSS transform method.

Transforming SVG Elements Using CSS

Cast your mind back to Chapter 4 – remember the preserveAspectRatio demo we built, which featured an image of an apple? I only ask, as it’s going for an en-core (oops, sorry!) in our next demo.

If we were to keep to a pure SVG solution, then we would look to use a tag such as <animateTransform>; this will work perfectly well, but it is overkill for our needs. Instead, we can simply make use of the standard CSS transform attribute – this is just as good, and would look something like this within code:
.406-87.378z" transform="translate(-181.4 -224.71)"/><path
This is a perfect example of a transformation within SVG – this is one of four options available for use. Each of them works in a similar fashion to CSS but use different arguments, which must be separated by whitespace or a comma. We can see all four summarized in Table 6-1.
Table 6-1

Transformation Options for SVG

Type of transform

Purpose of function

translate(<tx> [<ty>])

Move a shape to a specified set of coordinates – the tx value is along the x-axis; the (optional) ty value is for the y-axis.

rotate(<rotate-angle> [<cx> <cy>])

Rotate a shape x degrees, around point 0,0, or the cx and cy values (if they have been specified).

scale(<sx>, [<sy>])

Scale a shape up or down in size – the values specified represent the scaling values along the x- or y-axes respectively.

skewX(<skew-angle>)

skewY(<skew-angle>)

Skew an image on either the x- or y-axes, as appropriate.

matrix(a,b,c,d,dx,dy)

Define a custom transform using mathematical functions such as cos() or sin() – preference is to use transforms already listed in this table, if they can achieve the desired result.

For a detailed explanation of the math behind how transforms work, it’s worth having a look at the article on CSS-Tricks.​com, by Ana Tudor, at https://css-tricks.com/transforms-on-svg-elements/ .

We are by no means limited to just applying a single effect though – we can chain multiple transforms to achieve more complex results. All we need to do is simply leave a space between each effect; each will be executed in turn, so it’s important to get the order right!

To see what this means in practice, let’s pause for a moment and work through a little demo. For this, we’ll reuse that apple from Chapter 4, as a basis for combining a couple of transforms to rotate and move it on screen.

TRANSFORMING CONTENT

Let’s make a start:
  1. 1.

    Go ahead and extract a copy of the transform folder – save it (and the files within) to the root of our project area.

     
  2. 2.
    Next, open a copy of transform.html in your text editor, then look for this code, on or around line 10:
    preserveAspectRatio="xMidYMid meet">
     
  3. 3.
    We’re going to add a transform to the main SVG element – in our example, we’ll rotate it by 15 degrees. Add the highlighted code to our markup, then save the file:
    <svg width="200" height="200" xmlns:="http://www.w3.org/2000/svg" viewBox="0 0 300 550" preserveAspectRatio="xMidYMid meet" transform="rotate(15)  translate(20, 30)">
     
  4. 4.

    Go ahead and preview the results – if all is well, we should see something akin to the screenshot shown in Figure 6-2.

     
../images/461821_1_En_6_Chapter/461821_1_En_6_Fig2_HTML.jpg
Figure 6-2

Transforming our apple SVG image

This was admittedly a simple change to make, but we’re only scratching the surface of what is possible – why not try using one of the other transformation commands to see what happens or chaining multiple ones together? Try skewX(30) for example, – the result will put a whole new slant on things, so to speak!

As an aside – If we had to keep to a pure SVG solution, then take a look at transform-alternative.html in the code download; this is our apple demo reworked to use SVG for the main rotation effect. Note though, that you may see differences in behavior (such as here); it’s worth bearing this in mind when developing your solution.

Okay – let’s move on: if our demo had been more complex, then a CSS transform statement might not have been sufficient; instead, we need something that would cope with more complex animations. Fortunately, SVG has several options available, such as <animate>, <animateMotion>, and <animateTransform>. I feel it’s time for another demo (and yes, sorry, pun intended) – let’s dive in and take a look at this in more detail.

Moving Content with <animate>

In the previous demo, we touched on the use of transform to manipulate the position of our apple – for a simple demo, this CSS attribute works very well. However, what if our demo had been more complex, and that a simple CSS attribute would not be sufficiently powerful to handle the animation…?

Well, don’t worry – SVG can be animated using animation elements; these were defined originally in the SMIL Animation specification, but to which SVG has added some extensions that are compatible with the original specification.

Put simply, there are three SVG elements we can use when animating content: <animate>, <animateMotion> (for animating content on a motion path), and <animateTransform>. For now, we’ll focus on using simpler <animate>, which takes a number of parameters – these define the element to animate, where it should be animated, and for how long this animation should last. A full list of the properties is summarized in Table 6-2.
Table 6-2

Properties for <animate>

Property

Function

attributeName

Required – Must be a valid attribute on the element the animation is being applied to.

From

Optional – If left out, the animation will start at the current values of the selected attribute.

to

Required – The value the attribute should be animated to.

dur

Required – The duration of the animation; we can use time values such as 2s or 1300ms.

href

Required – If our animation is outside of the element being animated, we can specify the ID of the element.

begin / end

Optional – Specifies when the animation should begin or end, such as on a click.

fill

Optional – Specifies what should happen when the animation is completed, such as freeze (remain as the animation ends), or remove (remove any effect the animation had on our element).

Now – anyone spot that I dropped a pun toward the end of the previous section, but that I didn’t allude to what that pun was? Well, it’s time to reveal all – it seems somewhat apt that our next demo will feature a working clock, and that it’s time (sorry!) to take a look at how the properties of <animate> work, in more detail.

Creating a Clock Using <animate>

When working with SVG animation, there are a whole host of use-case scenarios where animation could be applied – take, for example, the Fourier Père et Fils site we visited at the beginning of this chapter, which adds little extra touches that give the site some added sex appeal.

Sometimes though we may have a more practical need to animate SVG – for our next demo, we’re going to put our spin on a demo created by Mohamad Mohebifar, which you can see at https://codepen.io/mohebifar/pen/KwdeMz . This is a basic clock, but I’m going to tweak the styling, and use JavaScript to insert longer lines at the 3, 6, 9, and 12 o’clock positions. It’s worth taking a closer look at this demo, as it makes good use of JavaScript to help animate the hands – we’ll explore this in more detail at the end of the exercise.

USING <ANIMATE> AND JAVASCRIPT

Okay – let’s crack on with our demo:
  1. 1.

    We’ll start by extracting a copy of the animatetag folder that is available in the code download that accompanies this book – save it in our project folder.

     
  2. 2.
    Next, we need to start adding our markup – the first is add a background shadow effect; add the following code immediately after the opening <svg> tag:
          <filter id="innerShadow" x="-20%" y="-20%" width="140%" height="140%">
            <feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur"/>
            <feOffset in="blur" dx="2.5" dy="2.5"/>
          </filter>
     
  3. 3.
    Next, we’re going to add the two circles that form our clock – drop these two lines in immediately after the closing </filter> tag:
          <g>
            <circle id="shadow" style="fill:rgba(0,0,0,0.1)" cx="97" cy="100" r="87" filter="url(#innerShadow)"></circle>
            <circle id="circle" style="stroke: #FFF; stroke-width: 5px; fill:#c0c0c0" cx="100" cy="100" r="80"></circle>
          </g>
     
  4. 4.
    The third block contains the code that displays (and animates) the hour, minute, and second hands – go ahead and add this code in, immediately before the closing </svg> tag:
          <g>
            <line x1="100" y1="100" x2="100" y2="55" transform="rotate(80 100 100)" style="stroke-width: 3px; stroke: #fffbf9;" id="hourhand">
              <animatetransform attributeName="transform" attributeType="XML" type="rotate" dur="43200s" repeatCount="indefinite"/>
            </line>
            <line x1="100" y1="100" x2="100" y2="40" style="stroke-width: 4px; stroke: #fdfdfd;" id="minutehand">
              <animatetransform attributeName="transform" attributeType="XML" type="rotate" dur="3600s" repeatCount="indefinite"/>
            </line>
          <line x1="100" y1="100" x2="100" y2="30" style="stroke-width: 2px; stroke: #C1EFED;" id="secondhand">
              <animatetransform attributeName="transform" attributeType="XML" type="rotate" dur="60s" repeatCount="indefinite"/>
            </line>
          </g>
     
  5. 5.

    Save the file – if all is well, we should see a clock ticking, when previewing the results in a browser, as indicated in Figure 6-3.

     
../images/461821_1_En_6_Chapter/461821_1_En_6_Fig3_HTML.jpg
Figure 6-3

Creating an SVG clock using <animate>

Although we now have a working clock, some of you may have noticed the presence of this line in our code:
<script src="js/animatetag.js"></script>

The sharp-eyed will have noticed we’ve not made reference to this in our demo – it is with good reason: our demo is about using <animate> so we should, of course, focus on this first! Nevertheless, we can’t achieve the effect without some JavaScript, so let’s pause for a moment and take a closer look at our code.

Dissecting Our Code

If you cast your mind back to Understanding the different methods, from earlier in this chapter, you will remember that we touched on several different ways to animate SVG content. In our clock demo, we’ve used two methods – not only did we use the SVG <animate> tag, but also plain JavaScript.

If we delve into the code, we can see there isn’t anything out of the ordinary; we kick off with creating an array, into which we cache the selectors for the hour, minute, and second hands.

We then work out the current time, based on using Date() – this is then used to set where the hour, minute,, and second hands should be displayed on the clock face; we pass each value into the hands[] array. We then set the position of each hour on the clock – this is done in two stages: the first for statement takes care of any number that is not 3, 6, 9, or 12. The second function fills in the gaps with the remaining numbers, to make up our clock face.

Now – creating a clock is great, but it’s still something of a theoretical example: how about creating something a little more down-to-earth and practical? Well, one example that comes to mind is a loader – you know, the little spinner we get when waiting for content to be displayed on anything less than a superfast connection! The <animate> tag is perfect for this, so let’s dive in and take a look at an example in more detail.

Creating Animated SVG Loaders

If you spend any time surfing the web, then you will no doubt come across a spinning icon of some description; a search using Google will show dozens of examples created using the likes of CSS or a graphics package such as Photoshop.

As a format, SVG is perfect for creating animated spinners, if for one reason only – their responsive nature means we can create and adjust their size without any loss of quality. To illustrate this in action, we’re going to build a quick demo that shows off three different types of spinning icons, as a Codepen demo.

CREATING A LOADER

Let’s make a start on creating that demo:
  1. 1.

    First, browse to Codepen at https://www.codepen.io , then click on Create.

     
  2. 2.

    From the loader folder in the code download that accompanies this book – copy and paste the contents of html.txt into the HTML pane.

     
  3. 3.

    From the code download – copy and paste the contents of css.txt into the CSS pane.

     

You might want to click on Change View | Editor Layout, then right-click to change the page layout if it makes it easier to view the demo.

  1. 4.

    Go ahead and save the pen as Anonymous (this is perfectly fine for the purposes of this demo).

     
  2. 5.

    If we preview the results in a browser, we should see three random loaders running, as indicated in Figure 6-4.

     
../images/461821_1_En_6_Chapter/461821_1_En_6_Fig4_HTML.jpg
Figure 6-4

Creating loaders using SVG

Understanding How the Code Works

Although this appears to be a simple demo, with little CSS in use, much of the magic takes place within the SVG elements we’ve added to the HTML pane. Let’s take a moment to explore this code in more detail, as it contains some useful tips for us:
  • All three spinners are made up of nothing more than standard SVG elements, with an <animate> tag embedded within – in this case, we have <circle> (in the first spinner), <path> (used in the middle spinner), and <rect> (used in the right spinner).

  • You will notice that in comparison to other demos, the initial <svg> tags may appear stripped back, and to be missing some of their attributes. This is intentional – not all of the tags are required for an SVG to be rendered, and that what we have here is sufficient for our needs. Indeed, specifying size attributes within the SVG would be pointless, as they would be overridden by our CSS style rules!

  • If we take a closer look at each animate statement, notice though how we’re using two different tags to animate the SVG elements? In the first spinner we make use of the <animate> tag; the remaining two make use of <animateTransform>. There is a subtle but important difference between the two – the first will animate any property or attribute of an element (including to a new location on screen). Unfortunately IE9-11 don’t support CSS transforms on SVG elements, so we must use <animateTransform> instead, if our project requirements dictate these browsers should be supported.

  • A closer look at these statements will show that we have some common attributes in use: we, of course, have attributeName (for the attribute being animated), the dur property to control the length of the animation, and the values property to determine how the animation should run. All three demos make use of the <begin> property, to introduce a slight delay – this is particularly important for the third demo; otherwise the animation will look rubbish!

There is one very important tip that we have yet to cover – all of the animations we’ve created thus far have been single animations. What if we needed to create something that required multiple animations, such as moving and scaling a box at the same time?

Much of this will depend on how we propose to animate our SVG element  – can we use CSS, or do we need to use native SVG or a JavaScript solution instead? Each will offer its own benefits – there is one crucial point though, which must be considered over and above any solution: Question is, any ideas as to what that might be…?

Managing Multiple Animations

Well – what is the answer to that question, I hear you ask? It’s simple – it’s all about timing.

Okay, at the risk of stating the obvious, timing is indeed key to running multiple animations; it’s where we not only need to understand our code, but also the impact that code has as part of the bigger picture.

It’s important to understand that SVG animations (and for that matter, CSS-based ones), are always processed in a single pass. This means we need to be mindful of what happens, and when – to control the flow, we can introduce delays using properties such as animation-delay (CSS), or delay (SVG).

I’m a great believer in the KISS principle (Keep it Simple…you get the idea!) – for me, a more effective animation is one that provides a nice touch rather than one that takes over everything else. Remember that example of the flying birds we talked about at the beginning of this chapter? This (for me) is a great example of how simple animation works well – not only is the overall design kept simple, but the SVG animations do not overtake the overall design.

So – how could we translate this into real code? Well, assuming we decide to use native SVG as our solution, one approach we can use is this:
  • We first encompass our SVG element within a set of <g> or group tags – this is to prevent cross-contamination with other SVG elements.

  • We then add our second animation in immediately after our closing shape tag, but before the closing </g> tag.

Seems simple enough, right? This is ideal for instances where we might only want a couple of animations per SVG element, but what if we needed more? Take, for example, this Codepen demo I’ve put together, at https://codepen.io/alexlibby/pen/OvjEOR , and a version of which is reproduced below:
<svg width="275" height="275">
  <rect x="10" y="10" width="20" height="20"
    style="stroke: black; fill: slategrey; style: fill-opacity: 0.25;">
    <animate attributeName="width" attributeType="XML" from="20" to="200" begin="0s" dur="8s" fill="freeze"/>
    <animate attributeName="height" attributeType="XML" from="20" to="150" begin="0s" dur="8s" fill="freeze"/>
    <animate attributeName="fill-opacity" attributeType="CSS" from="0.25" to="1" begin="0s" dur="3s" fill="freeze"/>
    <animate attributeName="fill-opacity" attributeType="CSS" from="1" to="0.25" begin="3s" dur="3s" fill="freeze"/>
  </rect>
</svg>

At first glance, you might be forgiven for thinking this would collapse into a heap, with four animations clashing! But it doesn’t – if you look carefully at the code, you will see that delays have been introduced, to help manage the effect. We are also using two types of animation – it’s the same <animate> tag in use, but we’re animating both XML and CSS properties (hence the use of animateType). This shows that, with some careful planning, we can produce effects that work well, and achieve the desired result.

At this point let’s change tack – we’ve used the native SVG <animate> and <animateTransform> elements to add motion to our SVG elements. This works very well, but there will come a point where we may want to animate something more complex, which will take us beyond the limits of what these two elements can handle.

Fortunately, we are not short of alternatives – these range from the popular Snap.svg library through to heavyweight alternatives such as D3 or GSAP. We’re spoiled for choice, so without further ado, let’s take a look at a selection of the possible contenders in more detail.

Working with Third-Party Libraries

If we’re working on a complex animation that needs the power of a heavyweight tool, then JavaScript is a good contender. There is a downside to using it though – it was never designed with animating SVG in mind, and it was developed as something more of a generic tool for manipulating content within the browser.

Don’t get me wrong – JavaScript is perfectly capable of animating SVG content, but it is not the only heavyweight option available: there are others we can use, which make the effort required easier. Let’s take a look at the list, which includes the following:
  • Two, available from https://two.js.org/  – a 2D library that requires the use of Underscore.js and Backbone.js events;

  • SVG.js, hosted at http://svgjs.com/  – a lightweight SVG animation package, which can achieve the same effects as some of its bigger brothers, but which has been optimized for speed.

  • Snap.svg, downloadable from http://snapsvg.io/  – arguably the most well-known and popular library available for animation (we’ll use it in a demo later in this chapter).

  • SnapFoo ( http://yuschick.github.io/SnapFoo/ ) – a relatively new library that extends the power of Snap.svg animation, to make it easier to develop using the library.

  • D3 (htp://​d3js.​org/​) – this veteran library has been around since 2011; it’s used for producing dynamic data visualizations using SVG, HTML5, and CSS3.

  • GreenSock Animation Platform (or GSAP – https://greensock.com/ ) – describes itself as a high performance, professional grade animation library, which can be used to animate SVG content.

  • Velocity (available at http://velocityjs.org/ ) – created by Julian Shapiro, this animation engine has the same API as jQuery’s animate and can be used as a drop-in replacement for jQuery.

  • Vivus (from https://maxwellito.github.io/vivus/ ) – this library provides a different take on SVGs; it allows you to animate them as if they were being drawn.

  • Anime.js ( http://animejs.com/ ) – this lightweight animation library includes support for SVG and works in all of the more recent browsers.

Note

You may hear of Raphael – this was the predecessor to Snap.SVG, and caters for very old browsers, such as Firefox 3. It has not been updated for several years.

There are dozens of other libraries available for SVG, so it is definitely worth a look online to see what is available – as with any option, it’s recommended you try out a few possibilities to see how they perform, before settling with your favored choice(s) of library.

To set you off on that path of discovery, we’re going to dive into a quick demo that introduces of the more popular options – Snap.svg. Although it looks and works in the same way as jQuery, it doesn’t require that library to operate; it does make it much easier to manipulate graphics! Let’s take a look at the library in more detail, to see why it is so easy to use.

Introducing Snap.svg

If you spend any time animating SVG content, then you will eventually come across Snap.svg. Originally created by Dmitry Baranovskiy, this library can trace its background to the days of Raphäel.js, which was originally released back in 2008 and soon became very popular.

It offered great support for browsers as far back as IE5.5, but this ultimately proved to be too limiting – it couldn’t keep up with what users were demanding, while still providing that backward compatibility; a complete rewrite to take advantage of what SVG can offer, resulted in what we now know as the Snap.svg library.

With the introductions out of the way, now is a good time to take a look at how it works – if you look closely at the code in the next demo, you will soon see some similarities to jQuery! We don’t need to make use jQuery though, which makes it easier to use: to see what I mean, let’s dive in and take a closer look.

INTRODUCING SNAP.SVG

Let’s make a start:
  1. 1.

    We’ll begin by extracting a copy of the snap folder that is in the code download that accompanies this book – save it in our project area.

     
  2. 2.

    Next, open up the snap.html file, then add the following line of code immediately after the <h2> tags:

    <div id="iconDiv"></div>

     
  3. 3.
    We have our SVG content in place, but need to animate it – for this, go ahead and add the following code to a new file, saving it as snapsvg.js in the js subfolder with our snap folder:
    window.onload = function () {
      var s = Snap("#iconDiv");
      Snap.load("./img/icon.svg", function(f) {
        whiteRect = f.select("#whiteRect");
        icon = f.select("#icon");
        icon.hover(function() {
          whiteRect.animate({y:960}, 500, mina.elastic);
        }, function() {
          whiteRect.animate({y:977.36218}, 500, mina.elastic);
        }
      );
      s.append(f);
      });
    };
     
  4. 4.

    Remember to save both files – if we now preview the results in a browser, we should see the screenshot shown in Figure 6-5.

     
../images/461821_1_En_6_Chapter/461821_1_En_6_Fig5_HTML.jpg
Figure 6-5

Our finished Snap.svg demo

Try hovering over the white square in the middle – you will see it move up and down; this movement will feel very elastic, thanks to the mina.elastic easing that has been applied in our code.

This is one of several easings that come built-in to the Snap.svg library; we could use one of these, but with a little help, we can create our own custom easing with little difficulty. Let’s take a look at how we might achieve this – there are several options available, which are all worthy of consideration.

Applying Easing Effects to Elements

When animating an element, we might be content with simply letting it move from position X to position Y. In many cases, this will suffice – there are occasions when we might want to add a little extra effect to that movement.

We can of course achieve this with an easing effect – Snap.svg comes with some built-in options such as easeIn, elastic, or bounce. These are similar to easings you might use elsewhere, such as jQuery – trouble is, things will get a little stale if we limit ourselves to just these attributes.

To see the built-in easing functions in action, head over to this Codepen by Mike Tempest: https://codepen.io/mike-tempest/pen/myvbrw

We can easily change this – with a little extra work, it’s possible to add in a custom easing effect using a cubic-bezier curve; don’t worry, this is easier than it sounds! Let’s dive in and take a look – to start with, we need to get our cubic-bezier values first.

Getting Prepared

The core part of our next demo centers on the use of a cubic-bezier curve – for the uninitiated, and assuming we had to plot it on a graph, our curve action would look something like that shown in Figure 6-6.
../images/461821_1_En_6_Chapter/461821_1_En_6_Fig6_HTML.jpg
Figure 6-6

Our cubic-bezier curve – Source: easings.​net

Unfortunately, a chart on paper won’t mean a great deal – to see how it works in action, we need to head over to http://easings.net/#easeInBack , which shows an example of this easing effect. If we wanted to refine its appearance, we can also do this – browse to http://cubic-bezier.com/#.6,-.28,.735,.045 , and slide around the circles within the main chart to fine-tune the values.

Assuming we now have our cubic-bezier values, we now need to implement it in our code – for this, we can make use of a simple plug-in created by Arian Stolwijk, and which is available at https://github.com/arian/cubic-bezier . I’ve included a refined version of this plug-in in the code download – the original code is a few years old, and contained a function that has been found to be buggy and can be safely removed.

Okay – let’s crack on: we now have our values, so time for us to get stuck into some code!

EASING CONTENT

For this next exercise, we’re going to add a custom easing, based on a cubic-bezier curve – let’s make a start:
  1. 1.

    First, take a copy of the snap folder from the code download that accompanies this book – save it as snapeasing in our project folder.

     
  2. 2.
    Our cubic-bezier plug-in is in the js subfolder – we now need to tie this into our demo. For this, go ahead and add the following lines of code, immediately before the closing </body> tag in our demo:
          <script>
            var timing = bezier(0.6, -0.28, 0.735, 0.045);
            var paper = Snap(800, 800);
            var r =  paper.rect(0,0,200, 200).attr({fill: "darkslategrey" });
            r.animate({ x: 600 }, 1000, timing);
          </script>
     
  3. 3.

    Save the file – if all is well, we will see a dark gray square from the race across the screen (Figure 6-7), using the new cubic-bezier easing effect we’ve just added to our code.

     
../images/461821_1_En_6_Chapter/461821_1_En_6_Fig7_HTML.jpg
Figure 6-7

Applying a custom easing effect

This is a somewhat more complex yet useful way of adding a custom easing effect to any shape we animate using Snap.svg – it means we are not forced to have to use one of the built-in methods and can begin to use something a little more original. Although the code isn’t extensive (at least within the main markup file), it highlights a couple of useful tips – let’s dive in and take a look at our code in more detail.

Exploring the Code in Detail

Take a look at the code in the main markup file – our main markup now contains the code to initiate a rectangular SVG shape, using Snap.svg. This uses similar principles to the previous demo, except this time, we’ve added an extra function to translate our cubic-bezier value into something that can be understood by Snap.svg.

The key to making this work lies in the function created by Arian – we’re using a simplified version to allow for changes to browser support since the original function was created. The only way to see how this works is to dive into your browser’s Developer Console – it’s outside of the scope of this book, but if you want to get stuck into the depths of the code, you can see evidence of it in the Sources tab if using a browser such as Google Chrome. In short, we use the bezier plug-in to convert the values into something that can be rendered by Snap.svg, and apply this as an additional parameter to the animate statement in our code.

Thinking further afield, we may prefer to dial things back a bit, and use something a little simpler; fortunately, there is a plug-in available that reworks the well-known easing equations originally created by Robert Penner. The plug-in can be downloaded from https://github.com/overjase/snap-easing/ , and it is as simple as adding a link to it in the markup, then specifying the name in place of our existing easing code.

If you really fancy getting down and dirty with the source code for Snap.svg easings, then the functions for the built-in easings are available at https://github.com/adobe-webplatform/Snap.svg/blob/master/src/mina.js  – head to the bottom of the file for the code.

Okay – we’ve come to the end of our journey through animating SVG content: there is one small area we should cover off before moving onto the next chapter in our adventure. We’ve explored some of the options around how we animate content, but it’s worth taking a few moments to understand the impact of using each option, and how we can go about selecting the most appropriate solution for our needs.

Choosing Our Route – an Epilogue

Over the course of this chapter, we’ve explored a variety of different options to animate our content – each has its own benefits, with some being more suited than others to particular circumstances.

The question is – how do you choose which route to take? Is there a right or wrong answer, or does it depend on our requirements? These are valid questions – only you can answer, but here’s hoping the following pointers might help guide you to that answer:
  • The first question is – how simple is your animation? Is it just one layer of animation – if so, then CSS is probably a good bet.

  • Does your project require multiple instances of the same animation, or a host of different animations? Should these animations be chained, or run individually? Again, CSS is likely to be a good candidate here – timings may be an issue, but if you’re not chaining too many, then you should be OK.

  • Should your animations be fired at the point of your user interacting with an element, such as a hover or click? At this point, we’ll almost certainly need JavaScript to handle the event, but can get away with CSS for the animation effect, rather than having to use JavaScript to provide it.

  • Is your animation very complex, with multiple animations being chained, and where timing is super critical? If this is the case, then we will likely have to resort to using either JavaScript/jQuery, or one of the third-party libraries such as Snap.svg. The former is possible, but given that the libraries we’ve talked about are dedicated to animation, it makes sense to use these instead.

  • Consider whether your SVG element is one you could reuse at a later date, or in multiple places in your project. If either are true, or you have a particular preference to using native SVG, then the <animate> tag (or one of its sister tags, such as <animateTransform>) could be a better option at this point.

The old adage “there is never a right or wrong answer” frequently rings true in cases like this; there may be occasions where the right solution to animating your content is obvious, but more often than not, there will be different ways to crack that nut!

Using an SVG animation tool – something to consider:

Throughout the course of this chapter, we’ve explored how to animate SVG content manually, using CSS, the <animate> tag, and through the use of CSS and JavaScript. As an alternative, it’s worth keeping an eye out for an upcoming project – SVGator ( https://www.svgator.com ). The website is still in beta at the time of writing but claims to make SVG animation easy as drag and drop; early indications are promising!

Summary

Mention the word animating, and there would have been a time when the only answer might have been JavaScript – a perfectly valid option, but not always the right one today! Over the course of this chapter, we’ve discovered the ups and downs of how to animate SVG content, and we’ve seen there are other options available, such as native SVG tags or using CSS. Let’s take a moment or two to review what we’ve covered in this chapter.

We kicked off with a quick look at an example to understand how SVG could replace options such as video, before summarizing each of the available options for animating SVG content. We explored the first option, animating using pure CSS, in more detail, before moving onto covering the native SVG <animate> element. We created a couple of examples to understand how this works in more detail, before quickly exploring how we might manage multiple animations.

We then moved onto looking at the use of third-party libraries, such as Snap.svg, before learning how to apply them in a practical use-case scenario. We then dived into learning how to add that extra touch using custom easings, before rounding out the chapter with a section on determining how to choose the best option to use when it comes to animating SVG content.

Phew – we’ve certainly covered a lot: our journey doesn’t stop here though! Throughout the course of the book, we will cover a lot of code in various demos – the one key thing we should always to is to ensure it is optimized to be as efficient as possible. There are a few tricks we can use when it comes to SVG, which we will explore in the next chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.237.24