Constellations Effect
I've seen this effect a few times on websites that want to appear high-tech. I don't know the real name for it, so I call it "constellations" as it looks like stars connected to form abstract shapes. For a better impression open the demo in full screen view.
My first attempt at replicating it was quite innefficient, (although I did use techniquies such as keeping the stars in a grid that limited the number of neighbouring stars they had to each loop through) so over time I made a few improvements and learnt a few quirks of Canvas 2d drawing along the way:
- At first I had been clearing the canvas with
clearRect
; this sets an area of pixels torgba(0,0,0,0)
(transparent black). I then drew semi-transparent lines over that, which becomes slow due to the browser having to repeatedly mix two different transparent colours together as the lines get drawn. It turned out to be faster to fill the canvas with solid white, which was faster to draw transparent colour onto. - The next improvement I made was to swap from concatenating a string of
rgba()
values to keeping a constant black colour and only manipulating the global alpha of the drawing context. This meant not having to concatenate a string and values for every line drawn, but also not making the browser parse that string into a colour. Global alpha is also set directly with a number, without mucking about with strings, which is another bit of efficiency. - The transparency of the lines drawn varies based on distance between points; further away stretches the line thin until it disappears completely. I was using alpha transparency to accomplish this, but found that it was faster to literally draw thinner lines at solid black. Presumably the same line drawing algorithm is used whether the lines are 1px wide or not, which means removing transparency can only speed things up.
- Finally, I had implemented some interaction by making the "stars" dodge away from the mouse cursor if they were too close. Due to the inherent delay in passing mouse inputs through to the program, this felt a little laggy. However, at the time I was reading the mouse position, updating star positions, and then moving any stars that were too close to the mouse. This effectively meant they were reacting to where the mouse was on the previous frame - if instead I detected mouse proximity before updating the stars from their own velocity, I effectively removed 1 frame of mouse lag, which can feel like a big difference.
Of course, all of these changes are rather inconsequential against what could be the biggest improvement: rewriting the rendering to use webGL instead of canvas operations. At the moment, however, I'm happy to let it stay as it is.