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.
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.
Alright, enough talk let's get in action. Open your favorite code editor and start your browser. I have used sublime text 3 and chrome browser by google for this tutorial.
We will go step by step.
Step 1: Prepare html structure.
If you are familiar with Emmet. 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.
<!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.
<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:
Here, I have styled background and positioned div using CSS. You can get the CSS from the codepen 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.
- Quadratic Bezier curve
- Cubic Bezier curve
- Arc
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.
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,
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
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.
<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.
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...
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
M0 77
C 473,-40
1222,283
1920,136
V 359
H 0
V 67
Z;
third iteration
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:
<!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.
The id
of linearGradient
can be used in <path>
element's fill=""
attribute.
check the code below.
<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
Top comments (10)
Hello, what about performance against CSS or Canvas animations? This is pure gold, I tell you, it's a shame nobody seems to support it, but I may just be missinformed, is this being used extensively in current web design?
Hello Daei_F,
Thanks for the complement :)
I am a big fan of CSS and Canvas and have done couple of experiment with them for this kind of designs. However, I would consider doing animation with SVG in every possible way as at the end its pure HTML which is natively working on its own without any other support like css and javascript. Also it will reduce load on browser's rendering engine. People will soon start supporting this as I am seeing this kind of animation on a lot of webpages.
I've learned multiple things here.
Firstly pure html animation isn't anything I've explored or even knew about so I'm thrilled to try this out.
Secondly, you explained the curves perfectly.
Thanks for sharing!
Excellent post!! and it's sooo cool! I really love this kind of tutorials. Your interpretation of Bezier curve is super clear. I felt confused about this before. Figure with text is a good way. Looking forward to more tutorials from you.
Interesting. Good post.
I just added waves to my site, I might use this technique.
Thanks
Feel free to use it. Let me know if you have any issue. I would be happy resolve.
Thanks. Appreciated. 👍
I'll give it a test & see how it works out.
Very nice! How can the color be added to the animate tag to change the wave color, e.g. either with keyframes to suddenly alternate/flash green, then blue, then red, or to gradually transform the color via HTML hex code (#00ff00 to #00aaff for example)? I had a try using fill with values and keyframes timings with no success.
I thing that GSAP animations is performs better than CSS. examples of the GSAP logo animations: adsspirit.com/portfolio/animated-s...
Thanks for the comment.
I do agree with you that Green Sock has a great library to deal with. However, the primary goal here is to avoid use Javascript for such simple animation that can be done with html. Also, code of this tutorial is not even 1% in size of script that GSAP has. So, I would prefer using such HTML based animation if I am going to design just a section with such animation on my personal portfolio or landing page like website.
Hope you got my point. :)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.