Canvas spheres
05-02-2019
An experiment with HTML5 canvas, requestAnimationFrame and ESLint.
Inspired by a bed sheet from IKEA, I wanted to make a small application that copied the look. You can use it as a screensaver too! Having a visual result of the code I wrote was very rewarding. What should have been a small experiment ended up taking more of my time than I anticipated because I was enjoying myself.
The IKEA Smörboll bed sheets.
Canvas
Using the canvas element enables you to draw and animate shapes using javascript.
So, what does it do?
The application will draw spheres in multiple rows. For example: one row of 10 spheres starting at the Y-position 0. The size of the spheres is dependent on the amount of space available. This means that when the page resizes, the spheres will be smaller to make sure the requested amount fit within the row.
Using this logic, several rows of spheres are used to fill the page. The last rows are filled with 60 spheres each until the bottom of the page is reached.
There is also a setting that let's you configure how often a sphere should be skipped. I noticed some blank spots in the sheet and just had to implement this. At random some spheres will be skipped (you can see this by refreshing the page).
When the spheres are drawn, the application remembers if a sphere was skipped and what color the drawn spheres have. Because of this, resizing the page (which requires redrawing the spheres) results in the same drawing but smaller or bigger. If the application couldn't remember the spheres, redrawing them would give you a different result everytime.
Skins
It would be boring having just black spheres on a white canvas, the solution: colors. I chose some colors and put them into skins. Skins have a name, background color and several colors for the spheres.
If no background color is provided, a random color will be chosen from the sphere colors. That color will no longer be available for the spheres. An example of this is the bubblegum skin (select it using the controls in the bottom left and refresh the page).
When a sphere is drawn, a random color is selected from the skin's sphere colors.
The available skins at this point.
Animation
This is where I couldn't help myself and started spending way more time than required.
Using window.requestAnimationFrame() you can tell your browser that you wish to perform an animation and that the browser should execute a piece of code to update an animation before the next repaint. I made two animations, a wiggle animation and a bounce animation.
The wiggle animation reduces the size of the spheres just enough. Next, at random, the sphere is moved slightly (up, down, left or right) every frame. The amount the sphere moved is forgotten, so every wiggle starts from the sphere's original center.
The bounce animation makes all the spheres move in random directions and at random speeds. Whenever a sphere hits the edge of the screen it will bounce off and continue at the same speed but in a different direction.
Using the controls in the bottom left, you can select an animation and see it all in action. Resizing the screen will result in a reset of the animations.
Controls
Because I made several settings available and I felt it would be more fun to display them in one page rather than a couple, some controls were required. You can hide the controls using the little button at the top right. Now you know what I mean by skins and animations, the select boxes are fairly self-explanatory.
Changing the selected option will redraw all the spheres. That means the animation will always start from a freshly drawn page. Changing the skin will also redraw the spheres. The spheres are remembered per skin. Changing back to a previously selected skin (without refreshing the page) will draw the spheres in the same positions.
The selected options will be stored in the session storage of your browser. Session storage is remembered as long as the browser is open and the same tab is used. Opening a new tab also opens a new session and any configuration will be reset.
ESLint
I used ESLint to make sure my code was formatted correctly. It's a bit of a pet peeve, but I hate it when I'm not consistent when writing my code. ESLint keeps me in check, it prevents me from making mistakes and keeps my formatting consistent, I love it.