Pure HTML Animation - Animate SVG with <animate>
Tags: html, css, svg, animation
Published: 2019-06-18 19:17:54

##In this animation markup, there is no use of CSS or JS for animation purposes.

For a long time, everybody has been talking about CSS and JS animation or animation libraries. I am wondering why no one is talking about HTML `<animate>` tag.

I wish some big names around would have pushed this `animate` element of SVG to promote more development over it. Anyways, it is never too late to start something good. I am taking this initiative to start spreading awareness around the front-end community regarding `animate` element of SVG.

Let's understand SVG first in short. 

first thing first - [*W3schools is always a great start.*](https://www.w3schools.com/graphics/svg_intro.asp)
###What is SVG?
- SVG stands for Scalable Vector Graphics
- SVG is used to define vector-based graphics for the Web
- SVG defines the graphics in XML format
- Every element and every attribute in SVG files can be animated
- SVG is a W3C recommendation
- SVG integrates with other W3C standards such as the DOM and XSL

###Why SVG? I'll tell you.
- It's a Vector.
- Being vector it is scalable.
- Smaller file-size. (Average 5X smaller than png file.)
- Easy to modify using CSS and JS.
- Easily Animatable :) in less time. Also, no need for any animation software or image processors.


*Note :*
If you are a first timer to SVG, please get yourself some helpful information about SVG and it's relatives from [Sara Soueidan's Blog on understanding SVG Coordinate Systems and Transformations](https://www.sarasoueidan.com/blog/svg-coordinate-systems/).


Alright, enough talk let's get in action. Open your favorite code editor and start your browser. I have used [*sublime text 3*](https://www.sublimetext.com/) and [*chrome browser by google*](https://www.google.com/chrome/) for this tutorial.

We will go step by step.

###Step 1: Prepare html structure.

If you are familiar with [Emmet](https://emmet.io/). Just type `html:5` in your emmet enabled editor and execute it *for sublime text execution key is _Tab Key_*.

--OR--

*_Copy the code from below._*

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>SVG wave animation</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- Wave SVG Animation -->
  <div class="waves"></div>
	
</body>
</html>

```


###Step 2: Drawing a wave-like shape.

I am not good at drawing but, I can tell you that cubic bezier is something we can consider as a wave. So, we will draw a cubic Bezier curve.

```html
<div class="waves">
	<svg width="100%" height="200px" fill="none">
		<path
			fill="#454599"
			d="
				M 0 67 
				C 273,183
				  822,-40
				  1920,106 

				V 359 
				H 0 
				V 67 
				Z">	
		</path>
	</svg>
</div>

```
*Result should something like this:*

![Drawing a cubic bezier curve](https://thepracticaldev.s3.amazonaws.com/i/izwiuokylo3m0g4utn88.png)

Here, I have styled background and positioned div using CSS. You can get the CSS from the [codepen](https://codepen.io/liquidcharcoal/pen/rEeYrw) link of this project at the bottom.
Let me explain you first what's going on with those numbers and letters.

Welcome to the Matrix!
You need to know those green rainfall of numbers from the matrix. (Ignore it)

Okay So, there are three attributes attached to `<svg width="100%" height="200px" fill="none">` and they explain themselves pretty well.

Also, inside the `<svg>` element there is the element `<path>` and attached with two attributes `fill` and `d`. You still can understand that we are starting to draw a path with `<path>` element and filling it with color with `fill` attribute inside. But, hey! What's that `d ="1230948713294"` about? That's what your question is right? And that's what I want you to understand the most as it is the thing we are going to  play within this tutorial. 

## Curves Hannhh
There are three variants of smooth curves available to draw with SVG.

1. Quadratic Bezier curve
2. Cubic Bezier curve
3. Arc

![Three Variants of smooth Curves. From left -> *(i) Quadratic Bezier Curve, (ii) Cubic Bezier Curve (iii)Arc *](https://thepracticaldev.s3.amazonaws.com/i/bzil99msa778liyc971i.png)

We will work with *_cubic bezier_* curve in this tutorial. So, let's understand how it works.

If you have any experience with Illustrator or Sketch like softwares, or something like the pen tool you will understand it easily. But, if you do not have any experience with the pen tool,  nothing to worry about it. I will explain how bezier curve works at my best.

Bezier curve has two main points and we will call it a start point and end point, and each main point has their handles which we will call control points.

Let's understand with the figure below.
![Cubic Bezier Curve](https://thepracticaldev.s3.amazonaws.com/i/nw8h1iyobhwz5l0pzcww.png)

In the figure above:

_M *x,y*_ is _Start Point_
_C *dx1,dy1*_ is _Control Point_ for _Start Point_

_C *x2,y2*_ is _End Point_
_C *dx2,dy2*_ is _Control Point_ for _End Point_

That means,

```html
M 0 67                   M x,y
C 273,183                C dX1,dy1
  822,-40      -->         dx2,dy2
  1920,106                 x2,y2
```

*Important: we are using absolute Bezier curve in this example by using `C 273 ...`. If you want to use a relative Bezier curve you can change the **UPPERCASE** `C 273 ...` to  **LOWERCASE** `c 273...` however it will need modification in defining points.*

*Mozilla developer community has a great explanation guide for absolute and relative curves please visit [Mozilla Documentation for Cubic Bezier Curves](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve)*


###Step 3: Start waving the wave.

####Before we start animating wave, let's quickly review how we are going to do it.

We will do it with `<animate>` element of SVG. In addition, we will use some attributes of `<animate>` element. Firstly as we want the wave to keep waving itself, we will use `repeatCount="indefinite"`. Secondly, we will fill our wave with some color by adding `fill="#454599"` attribute. After that, we will target the `d` attribute from `<svg>` element with `attributeName="d"` and we will define the duration for the animation by adding `dur="12s"` attribute. Coming up next, we will talk about the `values=""` attribute.

```html
<animate 
          repeatCount="indefinite" 
          fill="#454599" 
          attributeName="d" 
          dur="12s" 
          values=""
></animate>
```

`values=""` attribute can be written in several ways depending upon the context where it is being used. On the other hand, if interpreter finds the specification of the list of `values`, the interpreter will ignore the values of the attributes `to`, `from` and `by`. *[Recommended article for more details.](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/values)*

In our case, we are targeting `d` attribute of `<svg>` element to modify the curve. We also have defined the duration of 12s, that means we can break the iterations in 4 phases of 3 seconds each. Let's start now...

```html
values="
        M0 77 
        C 473,283
          822,-40
          1920,116 
            
        V 359 
        H 0 
        V 67 
        Z;
               
        *second and third iteration will go here*       
        
        M0 77 
        C 473,283
          822,-40
          1920,116 
            
        V 359 
        H 0 
        V 67 
        Z;

"

```

You might be wondering why I am using the same value for two times?
It is because we will come back to where we started by the end of the fourth iteration of our animation cycle, and we will make some movements in the shape during the second and the third iteration.

Let's make the second and the third animation iteration now.

*second iteration*
```html
M0 77 
C 473,-40
  1222,283
  1920,136 

V 359 
H 0 
V 67 
Z; 
```

*third iteration*

```html
M0 77 
C 973,260
  1722,-53
  1920,120 

V 359 
H 0 
V 67 
Z; 

```

Basically, we are modifying values of points and handles between iterations and `<animate>` element will smoothen the transformation of points according to the duration of the animation defined with `dur="..."` attribute.

So, the final code should be something like this:
```html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>SVG wave animation</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- Wave SVG Animation -->
  <div class="waves">
    <svg width="100%" height="200px" fill="none">
      <path 
        fill="#454599" 
        d="
          M0 67
          C 273,183
            822,-40
            1920.00,106 
          
          V 359 
          H 0 
          V 67
          Z">
        <animate 
          repeatCount="indefinite" 
          fill="#454599" 
          attributeName="d" 
          dur="15s" 
          values="
            M0 77 
            C 473,283
              822,-40
              1920,116 
            
            V 359 
            H 0 
            V 67 
            Z; 

            M0 77 
            C 473,-40
              1222,283
              1920,136 
            
            V 359 
            H 0 
            V 67 
            Z; 

            M0 77 
            C 973,260
              1722,-53
              1920,120 
            
            V 359 
            H 0 
            V 67 
            Z; 

            M0 77 
            C 473,283
              822,-40
              1920,116 
            
            V 359 
            H 0 
            V 67 
            Z
            ">
        </animate>
      </path>
    </svg>
  </div>
  
</body>
</html>

```

Ohh, wait... Since this is my first article ever. I have a bonus for you.

Let me tell you how you can add the gradient to the wave.

To add gradient, we will add `<linearGradient>` element right before `<path>` element. Also, we will provide some attributes to `<linearGradient>` such as `id` and positions of gradient start and end, something like this `<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">`. 

Inside `<linearGradient>` element we will define the `stop` points of colors we want to use in our gradient. for more details over working with gradients in SVG please read this article on Mozilla developer network : [Grdients in SVG](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Gradients#SVGLinearGradient).

The `id` of `linearGradient` can be used in `<path>` element's `fill=""` attribute. 

check the code below.

```html
<svg width="100%" height="200px" fill="none">

  <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="#00B4DB" />
    <stop offset="50%" stop-color="#224488" />
    <stop offset="100%" stop-color="#0083B0" />
  </linearGradient>

  <path
    fill="url(#grad1)"
    d="
       M0 67 
       C 273,183
         822,-40
         1920.00,106 
  
         V 359 
         H 0 
         V 67 
         Z">
  </path>

...


```

Final output: [Check out the pen](https://codepen.io/liquidcharcoal/pen/rEeYrw)

{% codepen https://codepen.io/liquidcharcoal/pen/rEeYrw default-tab=result %}