Reputation: 15
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.
Upvotes: 0
Views: 318
Reputation: 371
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>
Upvotes: 0
Reputation: 2286
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.
Upvotes: 2