HTML Canvas & Vanilla JavaScript Animation Series 2 – Animated Clouds Effect

HTML Canvas & Vanilla JavaScript Animation Series 2 – Animated Clouds Effect


Hi everyone, welcome to the second part
of my canvas animation series where we use HTML canvas element and vanilla
JavaScript to create all different kinds of animated backgrounds. You can use this
for websites background or just to practice your coding skills. I
intentionally use vanilla JavaScript in this series for everything with no
libraries. I think it’s important to understand how pure JavaScript works
before diving deep into React or even jQuery as these introduce another layer
of abstraction and can confuse beginners. At least they confused me at first. If
you missed the first video in the series where I created floating particles
effect, you can see the link on the screen now or in the video description
down below. This video is independent and I will code everything from scratch. We
will introduce mouse tracking and few other cool tricks so this video will be
slightly more advanced than the previous one, but don’t worry I will explain
everything. Also don’t forget to like the video if you like my stuff and want me
to make more, subscribe to the channel and click the bell icon to get notified
when I release a new video. You can see the final effect running in the
background now. I decided to call it “animated clouds” because that’s what it
reminds me of, but if you have a better idea for the name, please let me know in
the comments. Also by the end of this video we will take a minute or two to
modify this effect and be a bit creative with it We start with a quick setup of our
index.html file, we link stylesheet and script file and create HTML canvas
element with an ID of “#canvas1”. In style.css file we create some basic
reset rules so everything appears the same in different browsers. We position
our canvas and give it a linear-gradient background. That’s all for index html and
style css files, we will not touch these anymore, everything else will be done in
script js file. Let’s declare basic variables grab, the
canvas element with getElementById and save it as a constant
I called “canvas”. We give our canvas two dimensional rendering context and save
it all under this “ctx” variable. Then we set canvas width to window.innerWidth
and canvas height to window.innerHeight. This is just for the initial render, we
will later add window resize event listener to make sure canvas covers the
entire viewport at all times. I will initialize the “particleArray”
which we will later fill with individual particles, also we will need an array of
colours, each particle will be randomly assigned a colour value from this array.
We want particles to get bigger when they are within certain distance from
the current mouse position. Let’s declare “maxSize” and “minSize” variables which
will give us the range for our animation. Also make sure the value of “minSize” is
zero or larger otherwise you might get an error later. We will create a custom
object I called “mouse” and give it x&y properties, at first we set them to null.
Then we create an event listener for “mousemove” event. It accepts at least 2
parameters – type of event which is “mousemove” in this case – and a callback function.
This callback function has access to the “event” object which contains information
we will need. I will set our custom “mouse” object x value to event.x and mouse y
value to event.y. I will console.log the custom “mouse” object to test it. You
can see it is updating with the current mouse position. Now we create a “constructor function”.
These are used when you need a blueprint to create multiple objects of the same
type. All our particles will have X and Y
position value, directionX and directionY, which will determine how many pixels
is the particle moving each step, size and colour values. If the syntax seems a
bit weird to you try to read up about constructor functions, I will leave a
link in the video description. It is something that is commonly used. There
are other ways to create objects in JavaScript, but I think this is the best
way if you need to create many similar objects. We will also create a “draw”
method and instead of placing it on the particle object itself we’ll place it
directly on the prototype. I explained a bit more about this in the first part of
the series. It’s considered a good practice especially for performance
reasons. Our custom “draw” method will just contain code to draw one particle. In
this case we are using canvas “arc” method to draw a circle. This is the part of the
code where you can change the shape of our particles. I will show you how to
make a square at the end of this video and I will also show you how to draw stars
and other shapes later in this series. Another method we will need is “update”.
It’s a custom method so you can call it whatever you want. First we will check
where the particle is at the moment by making sure it’s x and y coordinates are
within the canvas. If the particle hits any walls we will switch its directionX
or directionY values. This will make it animate in the opposite direction.
I already explained how this works in the first part of the series. Keep in
mind these x and y values refer to the current particle’s coordinates and have
nothing to do with x and y values of the mouse object we declared earlier. Once
the animation is complete I will try to show you what exactly is happening
behind the scenes. I think it’s better to see it visually. Once we’re done we will move the
particles by adding its directionX and directionY value (which can be
positive or negative) to its x and y coordinates. It’s time to add mouse interactivity. If
you remember in the beginning we declared maxSize and minSize variables.
Let’s go back up and declare one more, which I will call “mouseRadius” and give
it a value of 60. This refers to the number of pixels around the mouse where our
particles will be growing. To check if the particles are close enough to our
mouse we will have to run couple of “if” statements. first I will check if the
current mouse.x minus current particles x-coordinate is smaller than mouseRadius value (which we set to 60 pixels). at the same time we want to check
if mouse.x minus this.x is bigger than minus mouseRadius. we are basically
checking if the current difference between our particles coordinate and
mouse coordinate is between minus 60 and 60 pixels. if this is true we know mouse
and the particle are close to each other and we animate the size up by nesting
another “if” statement, inside which we check if particles current size is
smaller than our maxSize we set maxSize to 40. So if it is smaller than 40
we will keep increasing its size by 3 pixels per step until it reaches the maxSize. Now we need to leave the nested statement go up one level where
we checked for the mouse position and do “else if” statement. This will only take
effect for particles that are not close to the mouse and we decrease their size
until they reach our minSize value. It is important to use “else if” here
otherwise you will get jiggles, because the particles are trying to change size
over and over. Also for some reason I had to include
check to make sure our particles are not smaller than 0 even when I set minSize
to 0. I think I’m missing something here, this rule should not be necessary. If you
see my error in the logic somewhere please let me know in the comments below. Once we run all these checks we are
ready to draw our particle with this.draw() Now we need a function that
generates values for each individual particle and creates an array of our
particle objects, which will hold our data. We already declared particleArray
variable, we will assign it to an empty array. Then we run a “for” loop. I
will run it thousand times, that number determines how many particles we
create. We have to declare the size first, as we will need the size value to
calculate starting x and y position coordinates. X position will be a random
number between 0 and innerWidth of our canvas, while I put buffer of double of
the current particle size on each side, to make sure we don’t get
stuck in the wall. We do the same for our y coordinate with innerHeight. DirectionX and directionY will be a
random small number. I want our particles to be moving very
slowly. Earlier we created a colour array. We have
four colours white, white with opacity, light blue and light gray with opacity.
We will set colour for each particle to be a random colour from these four
options. To make the code dynamic in case we add more colours to our array
later, we can do a random number between 0 and colors.length. This will give us
floating point number so we have to wrap it in Math.floor.
It might look confusing to a beginner but all we’re doing here is getting a
whole number between 1 and 4 in this case so we have
colors[1], which will return white for example. Then we create
a new particle object with all these randomized values by calling new
particle and we push it into our particleArray and the for loop will do
this a thousand times for us. We are ready to create animation loop. I will
call the function “animate” and use requestAnimationFrame API for smooth
animation. Also every frame we want to call clearRect and give it canvas
dimensions to clear the old paint. This will just delete our canvas over and
over. For each frame we will run “update” method on each individual particle to
check for position, move it and draw it. I call init() and I call animate() it
doesn’t work I’m getting some errors. Here let’s see I misspelled function
here it’s particleArray not particlesArray it spelled “this” and it’s Math.PI Yes we are up and running now. You can
see the canvas is stretching when we resize it. We want to update the canvas
size and redistribute the particles in the new available space whenever user
resizes the window. I will create an event listener for window
resize event and whenever user resizes the window we
will update innerWidth, innerWeight canvas.width, canvas.height and we will run
“init” function again to redistribute our particles in the newly available space. Yep! Also you can notice particles stay in the
corner if mouse leaves the canvas, because that’s the last known mouse
position. I want to remove the coordinates every second to make sure we
don’t get this behaviour. I can just do setInterval() and give it a callback function
which will set mouse.x and mouse.y to undefined every second. So that’s all
done for the basic effect let’s quickly review the code if you get any errors
you can pause the video and make sure your code is the same as mine. Last
thing I want to do is to show you some modifications. We can for example change
the background in our CSS file. In the script file we can for example alter our
colour array and give particles different colors. Down in mouse interactivity we can
change how fast our particles are growing and shrinking. Like this. In the draw method we can also change
the shape of our particles. Instead of arc method we can use fillRect and
draw squares we need to give it x&y coordinates and size values. Like that. We can also add a strokeStyle and call
stroke() to outline our particles. I can go on and on.
You can try to create some unique animations with this yourself. Anyway
that’s all for today, thank you very much for watching, don’t
forget to like the video if you liked it, subscribe to my channel and click the
bell icon to get notified when I release a new video. See you next time ! 🙂

24 comments

  1. How long does it take to figure this shit out? Jesus Christ, it's so unintuitive to animate with code, but it's really cool and probably ultimately easier in a lot of ways.

  2. Awesome tutorial again, Frank! Could you can do particle-js-like animations sometime later? Particle-js by itself is also cool, would love to see your interpretation and creativity on it. Keep up the videos. Also, huge thanks for teaching.

Leave a Reply

Your email address will not be published. Required fields are marked *