0

I have elements moving downwards which can be paused and resumed by pressing the P key. I tried every jQuery pause plugin out there, however once I pause the animation it won't resume. What am I doing wrong?

Spawning code:

$(document.createElement('img')).attr('src', source).
    attr('class', 'snowflake').
    css('left', x + 'px').
    prependTo('body').animate({ bottom: '0' }, 5000, 'linear');

Pause function (called when the P key is pressed):

Snow.togglePause = function (label) {
    'use strict';
    if (Snow.paused) {
        $('.snowflake').fadeIn(250);
        $('.snowflake').each(function() {
            $(this).resume();
        });

        Snow.paused = false;
    } else {
        $('.snowflake').fadeOut(250);
        $('.snowflake').each(function() {
            $(this).pause();
        });

        Snow.paused = true;
    }
};

I also tried replacing the each function with just $('.snowflake').resume(); and it didn't work.

Edit: The solution was simple. I solved it in a couple of minutes when I sat down and did the math after Matthew pointed me to the right way. Here's the final formula. https://i.sstatic.net/gs8mj.png

In my case the duration after resuming is DOCUMENT_HEIGHT * 5000 / ELEMENT.css('bottom'); Document height is the distance covered if not paused as the element will move from the top to the bottom. 5000 is the speed I chose at the start and the bottom property of the element is the distance the element will cover when resumed. This makes the speed constant and solves the problem. Thank you all for your help.

If you're a user trying to get the equation yourself, simply equate the speed at the start with the speed at the end and use v = d / t to get the formula.

2 Answers 2

2

It looks like to achieve this you will need to use queue and dequeue (and clearQueue):

There is some information on it here with a nice little demo:

http://api.jquery.com/clearQueue/

Essentially you are creating a queue for your animation and then dequeuing it when someone hits the pause button and queuing it up again when they hit resume.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried a similar approach, basically I would stop the animation on pause and animate the objects again, however because of the same duration parameter and a different distance the object needs to cover, when "resumed" the objects move a lot slower, so I need either a different approach, or a formula to calculate the duration when unpaused.
The demo doesn't seem to suffer this problem and animates the box using left as well?
Yes, but it changes the duration from 5000 to 1500 the second time. However that's till a constant and may be incorrect if the animation is paused at the top, which happens in my case.
0

If you using jQuery 1.8 and above, you can use progress function callback in animate method.
Link to animate documentation : http://api.jquery.com/animate/

You can save the state of the current animation in the element and restore it later.

Example (it's a draft, feel free to upgrade):
Link to the example : http://jsbin.com/egemaTA/2/edit

<!DOCTYPE html>
  <html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
    <script>
      $(document).ready(function(){
        var $mydiv = $('div').animate({ bottom: '0' }, {
          duration : 5000,
          easing : 'linear',
          progress : function(animation, progress, remainingMs){
            $(this).data('stay', remainingMs);
          }
        });

        $('#stop').click(function(ev){
          $mydiv.stop();
        });
        $('#go').click(function(ev){
          $mydiv.animate({ bottom: '0' }, {
            duration : $mydiv.data('stay'),
            easing : 'linear',
            progress : function(animation, progress, remainingMs){
              $(this).data('stay', remainingMs);
            }
          });
        });


      });
    </script>
    <style>
      html, body{
        height : 100%;
      }
      div{
        position : absolute;
        bottom : 100%;
        width : 50px;
        height : 50px;
        background-color : lightblue;
      }
    </style>
    <meta charset=utf-8 />
    <title>JS Bin</title>
  </head>
  <body>
    <div></div>
    <button id="stop">Stop !</button>
    <button id="go">Go</button>
  </body>
  </html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.