jquery-pendulum

jQuery pendulum. Animation around a pivot point

If you want to get straight to a working demo showing animation around a pivot point, view the jQuery pendulum animation here

The key to rotating an object element around a pivot point, such as a basic pendulum, is to setup your object (DIV element, or multiple DIVS) within a container element. The container acts as the pivot object that we animate and the child element(s) are offset to the location of the pivot centre. In this example I’ve used a single image as the child object – the ball and string – and absolutely positioned the top part of the pendulum to the centre of the container DIV.

The HTML and CSS setup for pendulum setup are as follows:

#pendulum-child {
	width:105px;
	height:623px;
	background-image:url(pendulum.png);
	position:absolute;
	left:-41px;
	top:10px;
}

#pendulum-parent {
	width:22px;
	height:22px;
	background-image:url(pendulum-pivot.png);
}

 

<div id="demo-container">
	<div id="pendulum-parent">
    	<div id="pendulum-child"></div>
    </div>
</div>

As you can see the layout is very simple; two divs for the pendulum object – one acting as the object itself and a container div acting as the pivot point.

Next we create the animation in jQuery and all we need are three jQuery files. jQuery (obviously), ‘jquery css transform’ which allows us to do basic CSS3 transforms including translate, rotate and scale and the ‘css transform animation’ which, as the name suggests, allows for these transformations to be animated:

  1. jQuery
  2. jQuery css transform plugin
  3. jQuery css transform animation plugin

Using the regular jQuery ‘animate’ command, combined with the ‘rotate’ property, we can animate and rotate a html element as follows:

$('#divname').animate({rotate: 20},2000, "swing");

Where “20″ is the degrees to rotate the div by (positive or negative), “2000″ is the time in milliseconds and “swing” is the easing mode. jQuery has two animation easing modes. Linear and Swing, with swing being the default. Swing easing – or “slow fast slow” – is ideal for pendulum motion. The pendulum starts moving slow at the start of its swing, is fastest halfway through and slows down towards the end of the swing.

The full jQuery code for the pendulum animation is below and only a few lines are required.

<script type="text/javascript">
(function($) {
        $(document).ready(function() {
			var rotation = 30;
			var swingtime = 1600;

			function init() {
				$('#pendulum-parent').animate({rotate: rotation}, 0, function () {
					$('#pendulum-parent').css("display", "block");
					rotation *= -1;
					pendulumswing();
				});
			}

			function pendulumswing() {
				$('#pendulum-parent').animate({rotate: rotation},swingtime, "swing", function(){
					 rotation *= -1;
					 pendulumswing();
				});
			}

			init();
	});
})(jQuery);
</script>

There’s two variables; ‘rotation’ which sets how high the pendulum should swing and ‘swingtime’ which is the length it takes to complete one swing. The init function sets the initial position of the pendulum by instantly rotating it to it’s start position (before displaying it) and the swing function which is called at the start of each swing, reversing the direction of the rotation as it does so.

Important to note that the rotation transformation is not compatible with Internet Explorer 8 and below or really old versions of Safari and FireFox. As these older browsers are declining in market share, I’m seeing more of these kinds of transformations being used. One of the best examples for pivot point animation is how Apple use CSS3 transformations on their iPhone page to create great transitions, which uses plenty of images rotating around pivot points. If you try this in IE 8 however, a standard slider appears instead.

Update: FireFox 16 handles JS transformations differently, so if your jQuery animated rotations are greatly exaggerated, you should try updating to the latest version of the plugin: https://github.com/zachstronaut/jquery-animate-css-rotate-scale

Update 2: A strange bug has sometimes been causing the pendulum to freeze occasionally mid-swing. This can be fixed by changing the ‘swningtime’ variable to an odd number – e.g. 1603 instead of 1600. Not 100% sure why this occurs but probably has something to do with the rotational calculations being set to zero between the positive and negative rotational swing.

Update 3: Added a ‘swings’ variable to get the pendulum to come to a rest after a certain number of swings.

26 Responses to “jQuery pendulum. Animation around a pivot point”

  1. Angie says:

    This was exactly what I needed. Thank you!

  2. John says:

    Many thanks for this, but how might I invert the pendulum – that is move the pivot point to the bottom, so that we have an effect like flowers on stems swaying in the wind.
    Thanks

  3. Hi John,

    The best way to invert the pendulum and change the pivot point would be to move the child DIV in relation to the pivot point parent. In the demo above, if you change the CSS for “top” for #pendulum-child to a negative value, such as -400px, that should do the trick. You may also need to move the parent container down.

    Tom

  4. John says:

    just what I needed thanks

  5. Kevin says:

    Nice work, keep going!

    But i’ve a question, how can I make the time infinity?

    I tried to set this more milliseconds;
    $(‘#divname’).animate({rotate: 20},2000, “swing”);

  6. Amrita says:

    Awesome… got it to work… just need to put in my own images now…
    As they say, one can never have enough. I was wondering if i could have like multiple pivot points … one pivot point per child so it could llook like parallel pendulums (i hope that makes sense) but KUDOS !!

    Thanks,
    Amrita

  7. Rohit says:

    this the best one.

    but it suddenly stops swinging. in all browsers

    probably it also needs jquery easing plugin. i used it and it worked for me

    • Thanks for pointing out this problem Rohit.

      I was able to replicate the bug and what fixed it for me was to change the time per swing to an odd number. I did first try and use the Easing plugin as you suggested but that didn’t work for me.

  8. Dhruv says:

    Hey Tom,
    How would you stop the pendulum in the middle of its movement?
    Thanks,
    Dhruv

    • Hi Dhruv,

      Good question, I would be tempted to create a couple more variables at the beggining, e.g.
      var totalswings = 10;
      var currentswing = 0;
      then to stop the pendulum swing after a certain number of swings, replace line 18 in the javascript code above with:
      currentswing++;
      if (currentswing <= totalswings) {
      pendulumswing();
      }

  9. Dhruv says:

    Hi Tom,
    Dhruv again. Thanks for answering my question, but I realized I intended to ask something else. Would it be possible to stop the pendulum in the middle of its swing, at a certain radius?
    For example:
    In my code the person presses the spacebar, and the pendulum is supposed to stop exactly at the radius it was at the time he pressed it.
    How would I do that?
    Thanks,
    Dhruv

    • Hi Dhruv,
      Ah, no problem – to stop the animation of the pendulum instantly, you can use “$(‘#pendulum-parent’).stop();” – I’ve updated the code in the demo to include a button.
      Hope that helps
      Tom

  10. esther says:

    Hi
    Great work! Really what I needed.
    Only one little thing I don’t know how to fix it. I would like the pendulum slows down and stops slowly automatically after appr. 5 swings.
    Can you help me?
    tnx a lot!
    Esther

  11. hi tom.

    wants to control pendullum swing time on bahalf of user define value .please suggest me how i will do that .???

  12. Hi Tom

    I have another problem.I want to start the movement of pendulum from the pivote point,neither from left or right.
    Please suggest me what should we do now.

  13. webmistress says:

    This is awesome, Tom! Just what I’ve been looking for!

    I’m initiating the animation on hover, which works well, except the animation seems to begin at the rotation degree. Like from the side? So it jumps on mouseover straight to ninety degrees. Is there any way to start the animation from the still state, instead? So that it begins swinging up, instead of down?

    Thanks!

  14. Brian says:

    Hi, I modified this so that it’s a clickable interaction with 4 different ‘spokes’. Just wondering if you knew a way to modify the code so that it could go backwards to it’s starting position? That way if I click one, the others will go back.

Leave a Reply

*