We have to implement animations in our website over many occasion, and there are many types of animations library out there. but if we want to create one from scratch, which one we will choose. Let’s check how many type on animations are out there
1. Transition and transform
This are the basic css property for creating basic movement and visibility animations, like if we need to move an item a little bit, or increase it opacity gradually, transition is the best way to solve that. and transition runs in GPU by default so the process will be faster.
.class {
transform: scale(1.5);
transition-duration: 1s;
}
The above example will scale the element to 1.5 rate in a duration of 1s, we can have many animations like, scale, rotate, matrix, skew, etc…
Check out more transition examples on https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_transitions/Using_CSS_transitions
2. Keyframe
This are the best CSS way to animate any complex movement, we can use all types of css property inside the keyframes which we can decide over a from and to or percentage wise steps. using this we can do much complex things than plain animations. But keyframe are always bit sluggish when there is too much movement.
@keyframes show-up{
from {
opacity: 0
}
to {
opacity: 1
}
}
.class {
animation: show-up 1s forwards;
}
The above example will show an element from opacity 0 to opacity 1 in of 1s, ‘forwards’ means continue animation to keyword as final, otherwise after the duration it will access the class original property of opacity, We can also all ‘infinite’ to create infinite animation that loop between from and to.
@keyframes grow {
0% {
width: 0
}
50% {
width: 100%
}
100% {
width: 0
}
}
.class {
animation: grow 1s infinite;
}
The above example is the same keyframe using a % keyword to go through, rather than from and to we can add any css property in any time using keyframe, and can loop through this variables infinitely.
Note: Keyframe may have some support issue on old browsers of safari or firefox, so we need web-Kit derivatives of keyframes such as,
@-webkit-keyframes grow {
0% {
width: 0
}
50% {
width: 100%
}
100% {
width: 0
}
}
@keyframes grow {
0% {
width: 0
}
50% {
width: 100%
}
100% {
width: 0
}
}
Keyframes are basically control the duration and specific points style switch in animations, all other is just CSS, you can add any CSS property inside this keyframes to make it animate.
(Please don’t use display: none; 🤣)
3. Canvas
Here, we move out from CSS and use javascript straight for complex animations, imagine we want a 1000 particles to roam around you screen that listening to your mouse movement we can’t do such user interaction animation with straight CSS, so here we can use canvas animations. But this is not like plain CSS. It need a very good knowledge over Javascript and Mathematics, all are calculation's here. Basically we can draw shapes using canvas keyword at any position inside the canvas by providing a x and y coordinates, and if we want to animate any elements, just calculate a new position and redraw the shape, for fluency we have reanimate function that provided from javascript that automatically trigger in all frame per second gaps.
But plain canvas is directly running on CPU and the load on CPU on the client system can straight affect the animation performance, also the reanimate function trigger as per frame per second supported on the browser (Chrome: 120fps , safari: 60fps on 120 fps display). This could affect the fluency feel differently for different users.
<canvas id="cw"
>Animation creating multi-colored disappearing stream of light that follow the
cursor as it moves over the image
</canvas>
const canvas = document.getElementById("cw");
const context = canvas.getContext("2d");
context.globalAlpha = 0.5;
const cursor = {
x: innerWidth / 2,
y: innerHeight / 2,
};
let particlesArray = [];
generateParticles(101);
setSize();
anim();
addEventListener("mousemove", (e) => {
cursor.x = e.clientX;
cursor.y = e.clientY;
});
addEventListener(
"touchmove",
(e) => {
e.preventDefault();
cursor.x = e.touches[0].clientX;
cursor.y = e.touches[0].clientY;
},
{ passive: false },
);
addEventListener("resize", () => setSize());
function generateParticles(amount) {
for (let i = 0; i < amount; i++) {
particlesArray[i] = new Particle(
innerWidth / 2,
innerHeight / 2,
4,
generateColor(),
0.02,
);
}
}
function generateColor() {
let hexSet = "0123456789ABCDEF";
let finalHexString = "#";
for (let i = 0; i < 6; i++) {
finalHexString += hexSet[Math.ceil(Math.random() * 15)];
}
return finalHexString;
}
function setSize() {
canvas.height = innerHeight;
canvas.width = innerWidth;
}
function Particle(x, y, particleTrailWidth, strokeColor, rotateSpeed) {
this.x = x;
this.y = y;
this.particleTrailWidth = particleTrailWidth;
this.strokeColor = strokeColor;
this.theta = Math.random() * Math.PI * 2;
this.rotateSpeed = rotateSpeed;
this.t = Math.random() * 150;
this.rotate = () => {
const ls = {
x: this.x,
y: this.y,
};
this.theta += this.rotateSpeed;
this.x = cursor.x + Math.cos(this.theta) * this.t;
this.y = cursor.y + Math.sin(this.theta) * this.t;
context.beginPath();
context.lineWidth = this.particleTrailWidth;
context.strokeStyle = this.strokeColor;
context.moveTo(ls.x, ls.y);
context.lineTo(this.x, this.y);
context.stroke();
};
}
function anim() {
requestAnimationFrame(anim);
context.fillStyle = "rgb(0 0 0 / 5%)";
context.fillRect(0, 0, canvas.width, canvas.height);
particlesArray.forEach((particle) => particle.rotate());
}
#cw {
position: fixed;
z-index: -1;
}
body {
margin: 0;
padding: 0;
background-color: rgb(0 0 0 / 5%);
}
The above example is a mouse movement listening animations, you can check the result here
https://medium.com/media/8c5528b355dba5f4e24fc2ef14def475/href
3. WebGl
This is the modern version for canvas that use a canvas to create the animation same as mentioned above but this is running straight on GPU, so the performance will be better. But WebGl is based on a shaders code that most developers will struggle to understand, this is mostly like writing all complex logics as a string shaders. learning curve for plain shaders is very high and the logic behind drawing shapes here are complex.
(Some browser system may not have GPU so we need a fallback canvas animation to prevent error pages)
you can check a sample WebGl2 animation here
https://medium.com/media/61b22e8094f3c12d71d1257547cbfbf3/href
We have some library out there for writing WebGl animations.
i. Pixi.js
Pixi js is a library for creating webGl 2D animations. We can use Pixi js API for drawing shapes rather than creating complex shaders, for example we can have Graphics animation for creating shapes like circle or triangle, and Sprite for creating images. Using this we can create complex animations that run in GPU and also we can control the frame per second to keep the uniq feel on all browsers
ii. Three Js
Three is a very popular and powerful 3D animation based on WebGl and WebGl 2 using three Js we can even create complex games in just a canvas with very good fluency. Three offer shapes images and complex movement logic API for creating complex animation without writing much Mathematical equations
There are many more WebGl library out there for use have a look on here https://en.wikipedia.org/wiki/List_of_WebGL_frameworks
Conclusion
Animations are important for you website visual appearance, but overcomplicating animations on website will affect the use cases of your website and users may switch for better usability than visual appearance, so its very important to have the balance between usability and visual appearance, with above examples you can choose between animation methods for the best balanced animation in your website that align with your specific use cases. Happy coding ;)