Reputation: 67217
The above picture states my scenario. When user clicks a button, i'm moving a
div
from Location 'A' [100,100] to Location 'C' [100,500] using Jquery Animate()
function, During that relocation, the div
should have to cross Location 'B' [100,250]. At that time, when it crosses the Location B i need to fire another animation.
Related to this problem i had surfed a lot and found this link.But it dont have an accepted answer. Additionally, Jquery has an event called Change
, But unfortunately it is compatible only with form elements
. My question is, can we handle events like postionChanged
or offsetChanged
in jquery manually if that really doesn't exist.? or is there any feasible method available to achieve my need.?
Thanks..!
Upvotes: 1
Views: 462
Reputation: 142
You need to test the animation through each step and run a function to test for the position. This is from the API documentation and can be easily repurposed for your animation.
$('li').animate({
opacity: .5,
height: '50%'
},
{
step: function(now, fx) {
var data = fx.elem.id + ' ' + fx.prop + ': ' + now;
$('body').append('<div>' + data + '</div>');
}
});
I made a fiddle for it. http://jsfiddle.net/MatthewDavis/6g8aP/1/
Upvotes: 1
Reputation: 8728
here is a working solution: i also used the step-event
HTML
<div id="#wrapper">
<div class="left"></div>
<div class="right"></div>
<div class="dot"></div>
</div>
<button class="go">GO!</button>
CSS
#wrapper {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.left, .right {
position: absolute;
top: 25px;
width: 100px;
height: 100px;
}
.left {
z-index: 1;
left: 25px;
background-color: red;
}
.right {
right: 25px;
background-color: green;
}
.dot {
position: absolute;
top: 72.5px;
width: 5px;
height: 5px;
left: 50%;
margin-left: 2.5px;
background-color: blue;
}
button.go {
display: block;
position: absolute;
top: 150px;
left: 25px;
}
jQuery
var $left = jQuery('.left');
var $right = jQuery('.right');
var $button = jQuery('button.go');
var $dot = jQuery('.dot');
var rightPos = $right.offset().left;
var dotPos = $dot.offset().left;
var thread = undefined;
var animationStarted = false;
$button.click(function() {
$left.animate({
'left': rightPos
}, {
duration: 1000,
specialEasing: {
'left': 'easeOutQuad'
},
step: function(now, fx) {
if (!animationStarted && now +$left.width() > dotPos) {
if (thread) { clearTimeout(thread); }
thread = setTimeout(function() {
animation();
animationStarted = true;
}, 0);
}
},
complete: function() {
$(this).after('<div>Animation complete.</div>');
}
});
});
function animation() {
$right.animate({
'background-color': '#0000ff'
}, {
specialEasing: {
'background-color': 'easeOutQuad'
}
});
};
Notice, that I used setTimeout inside the step-function to call the second animation in an other context. I'm not sure if it's good to run an .animate() call inside one running animation. To keep it smooth it's better to do it like this, i think. Does anyone knows it exactly?
The other point is the variable animationStarted. It just remembers if we called the second animation. That's the other thing to ensure not to call a complex animation inside the step-event of an other animation. With this way we surely call it just once.
Upvotes: 1
Reputation: 18780
jQuery.animate
takes an options argument that supports the following method (source)[http://api.jquery.com/animate/]
step Type: Function( Number now, PlainObject fx ) A function to be called after each step of the animation.
In your case the code would look something like:
$('div').animate({
left: 500
}, {
step: function(now, fx){
if (parseInt(now, 10) === 250){
// call your animation method here.
}
}
})
Upvotes: 1