Connect with:
About Me
Alessandro Annini
I'm a freelance developer currently working at Leaff.it/ I really love famo.us framework and its amazing potential and if you're like me, and you want the web to win, please share some snippet of code for the community and grow faster with us
Categories
Meta
Famo.us Code | Animated Dots Icon
622
post-template-default,single,single-post,postid-622,single-format-standard,ajax_updown_fade,page_not_loaded,,qode-theme-ver-6.2.1

Animated Dots Icon

23 Jul Animated Dots Icon

So, there I was, having a casual call with a friend of mine a few days ago. We used Skype to share some files, when I noticed that program has a circular processing/loading icon, which consists of a chain of small dots, running one after another. It looked nice and I wondered if I could replicate that in Famo.us.

First I needed to make one single dot. I decided to use a simple square white surface. If you set the border radius to half of the surface size, it will round it to the point that your square surface will become a circle:

var surface = new Surface({
   size: [height, height]
   properties: {
      backgroundColor: 'white'
      borderRadius: (height/2) + 'px'
   }
});

Next, I needed it to start circling around. I decided to use a narrow node, and place the dot inside of it at the top. Then I would just rotate that node around Z axis and it will move around my dot. That means that we would need each of our dots to be inside their own node and to follow their own angle and speed. I’m not a big fan of closures in JavaScript, so I am keeping the related data in the objects that require them. Here, each dot object would also keep it’s own look&feel, an angle transitionable (which will change in time) and a modifier, which will be affected by the angle:

for (var i = 0; i < this._amount; i++) {

    var joint = new Surface({ ... });

    joint.angle = new Transitionable( ... );

    joint.mod = new Modifier({ ... });

    joint.counter = 2;

    this.joints.push(joint);
    sizeNode.add(joint.mod).add(joint);            
};

I called them joints, as in joints of a chain. The joint.counter will contain the dot’s incremental step. We will use it to know the next angle the node should be rotated.

I also wanted to make the dots to be gradually smaller in size, so that the very first one would be the largest and the last one would be the smallest. To achieve it, I simply reduced the size of each new dot and node being added in the loop, which you have just seen above:

var joint = new Surface({
    size: [this._D-i, this._D-i],
    ...
});

joint.mod = new Modifier({
    size: [this._D-i, this._height-(15*this._height/100)-i],
    ...
});

 

Now, what is left is to loop our animation. Since all of the dots move at different speeds, I accomplish it with a check on ‘prerender’: if the first dot is idle (not moving) and the last dot is idle, then start moving all the dots. I would make a duration of the transition for each consequent dot just a little bit longer, so that they don’t move at the same speed and give me the effect I am after:

if (!this.joints[i].angle.isActive() && !this.joints[this._amount-1].angle.isActive()) {
    var angle = Math.PI * (this.joints[i].counter);
    this.joints[i].angle.set(angle, { duration: 1500 + i*this._delay, curve: 'easeInOut' });
    this.joints[i].counter += 2;
}

And that’s pretty much it! Feel free to rip it apart and use the bits you need 🙂 Here is the final result:

And here is one with the change from talve:

  • @LeXXik
    Here is an improvement to fix the diameter based on the number of dots you use:
    http://jsfiddle.net/talves/SumAT/3/

    The original would size them to 0,0 when there were more than the factoring. 🙂

  • @talves

    I’ve updated that function to incorporate your suggestion 🙂 Thanks!