Make awesome effects using physics and javascript

The Physics library

Elastic smooth movement is everywhere and I wanted to experiment with it a bit for my consultancy little web page at incoding.ztp.pt. Besides I had this effect in my head for some time now. I wanted to blow my divided photo away and reunite it again in different combinations, as you will see below.

Final attract example snapshot

I started to look around for a physics simulation library. It should be fast, in other words, it should have only exactly what I needed for accomplishing those effects and not much more that would slow the computations. And I really found it on this physics javascript library by Jono Brandel.

The library is pretty straightforward: setup 2D particles and forces between them and hit “go”.

The effects

Besides the effects that I have described for my photo, I wanted a similar effect for a word cloud. In fact the effect is the inverse of the one on my photo: instead of the mouse repel stuff, mouse pointer would attract stuff!

Attract

The intended effect is simple. As the mouse moves through the words’ cloud the words should attract to the mouse pointer, like as the mouse pointer was a magnet. As soon as the mouse pointer gets away a certain distance from a word, the word goes back to its original place.

Attract Example

Repulse

The effect for the photo is the exact opposite of the one for the words cloud. The mouse pointer should be a repel magnet for the 4 divisions of the photo. Also when the photo divisions get much away from each other, they should reunite in a different combination.

The Mouse-Magnets library

Since I’m using the barely same effect and I want to be DRY, I put up a small interface for setting up the two effects and use the same code for both. This code setup a physics model and takes care of updating the html objects’ positions.

The model

The physics model comprises:

  • fixed particle: fixed to the mouse pointer coordinates; shown in green in the diagram below.
  • free particle: floating object (e.g., a word in the words clouds) that will be repelled or attracted. Called “dolly” on the code, shown in blue in the diagram below;
  • fixed particle: anchor object (for each floater there is this helper particle) that is fixed in the rest position of its corresponding floating object; shown in black in the diagram;
  • attraction force: between each floating and its corresponding anchor particle;
  • attraction/repel force: one for each floating object and between it and the mouse pointer particle;

attract repel model

Setup

The setup involves creating the physics playground where the particles will exist and calculations will take place. The Physics library only needs two parameters for defining its world: gravity and drag. It will have no gravity and drag of 0.5. This particular value resulted only of experimenting to see which one achieved the motion I liked best.

Next, it is necessary to create all those particles and forces. So, for each floating object, the setup creates a javascript object with all info and adds it to an array to be available for later access. On this javascript object there are:

  • the floating object’s absolute position in the web page: as retrieved using the offset() jQuery function (top-left corner coordinates);
  • the floating object’s middle point position in the web page: this is the actual point coordinates that will be used in the physics model;
  • the floating object’s dimensions as helper info, since it is needed several times;
  • and the created particles and forces as described above as “the model” by using some helper functions of the Physics library.

After creating the world, particles and forces, some code must be added to some events:

  • physics world update: every time there is an update in the world (namely position of particles) the web page elements must reflect those changes;
  • mouse pointer movement: the pointer position must be transmitted into the physics world, by updating the corresponding particle;
  • mouse pointer enter and leave: the mouse pointer position only affects the physics world if it’s inside the enclosing area of the floating objects, so its effect needs to be disabled and enabled accordingly;
  • window re-size: if the absolute position of objects on page changes, then particles’ positions need to be reset, namely the anchor particles.

Finally just fire the thing up: the physics library has a play function that handles the animation loop for us.

Browser resize

If the browser resizes its window, the site elements will possibly re-arrange them selves since it is a responsive web site. In this case, the physics model must be specially updated since some coordinates were set at the beginning and never re-fetched again, namely the anchor objects. So, on browser re-size event, some coordinates must be re-fetched and calculations can proceed.

Detecting low CPU

The physics computations can become complex and slow, specially in the words cloud case described above since there are more than forty words, i.e., floating objects. On the photo effect, where there are only 4 floating objects, calculations are pretty fast.

I have checked on a top smartphone, and the effect in the words cloud was slower than acceptable and so, it should be disabled. The way to do this was to try to render the effect and check for the time it is taking, disabling it if it takes too long. This is accomplished by comparing the current time of the rendering to the last time of the rendering. This test must be positive for a few times in a row, to overcome momentarily lags of the browser.

Have fun.

Leave a Reply

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