returning the position of an element continuously - javascript

I have an object which is animated and falling from the top of the window to the bottom of the window. this works fine, but I would like to return the position of the element continuously.
At the moment I have this code
var pos = function() {
console.debug(jQuery('.element').position());
}
jQuery(window).on('mousemove', pos);
Which returns the position of the class "element" when the mouse is moving, I have also tried the event handler "live" but it is not working.
Is there any event handler I can use which will continuously return the position of them elemnt?
Thank you

Use .animate()'s step callback to track whatever you want, from position to timing:
var $test = $("span");
$("#element").animate({ top: 300 }, {
duration: 5000,
step: function(now, fx) {
$test.text( now );
}
});
#element{
position:absolute;
top: 0;
background:red;
width:40px;
height:40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span></span> px
<div id="element"></div>
http://api.jquery.com/animate/
A small suggestion, if you don't want to lose your fingers writing jQuery all over the place....
jQuery(function( $ ){ // DOM ready and jQuery $ alias secured
// Free to use $ as you usually would
});

You could use setInterval to execute a function at given interval.
setInterval(function () {
// do something here
}, 1000); // each 1 sec, starts after 1s

Related

Detecting the position of an element in the DOM being moved

I have been trying to find a working example of this but I think I am missing something very basic. I have a function to move the position of an element that is relative, I want to stop the element moving once the left element goes past 300px. I am using this code to move the element:
function tele_right(){
$(".tele-wrapper").animate({"left": "+=15px"}, 25);
}
I wanted to use something like this code to do something once in the DOM the left position hits 300:
if($('.tele-wrapper').css('left') == '300px') {
console.log('yay');
}
Any help would be much appreciated.
you can simply achieve this using offset() and a setTimeout: DEMO
function tele_right(){
var left=$(".tele-wrapper").offset().left;
if(left<300){
$(".tele-wrapper").animate({"left": "+=15px"}, 25);
setTimeout(tele_right,25);
}
else{
alert('passed 300 pixels');
}
}
tele_right();
If I was you, I'd just set the left property of your element to 0, then would do the animation all the way to 300px and define its duration to the desired value as follows:
$(document).ready(function() {
$(".tele-wrapper").animate({"left": "300px"}, 1000);
// 1000ms = 1 second, set this to whatever you like
});
.tele-wrapper {
position:relative;
left:0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tele-wrapper">tele-wrapper</div>

How to combine jQuery animate with css3 properties without using css transitions?

In this example; i am trying to create a jQuery animation with css3 rotate property. I can manage this animation with css3 transition and jQuery css() but i want to do this with jQuery animate() for rotating deg value according to my jQuery variatons.
Is it possible use animate with css3 property value with jQuery 1.8.0?
Here is jsFiddle to inspect.
jQuery:
var rotateVal = 90;
//this method isn't working
$('.red').animate({
'transform':'rotate('+rotateVal+'deg)'
},500);
//this way works but i don't want to do this with transitions
$('.black').css({
'transform':'rotate('+rotateVal+'deg)',
'transition':'1s'
});​
html:
<span class="black"></span>
<span class="red"></span>
Edit: Vendor prefixes removed, like -webkit-. Thanks to Kevin B.
It is possible, but it isn't easy.
var red = $(".red"),
rotateVal = 90;
$("<div />").animate({
height: rotateVal
},{
duration: 500,
step: function(now){
red.css('transform','rotate('+now+'deg)');
}
});
This basically creates a fake animation of a detached div, then on each step, updates the rotation of the target div.
Edit: Oops! wrong argument order. Here's a demo. http://jsfiddle.net/qZRdZ/
note that in 1.8.0 i don't think you need to specify all the vendor prefixes.
Using this method, you can animate almost anything as long as you keep in mind that things like += and -= won't work properly unless coded for.
Update: Here's a combination of my solution and cuzzea's solution abstracted behind a function. http://jsfiddle.net/qZRdZ/206/
$.fn.rotate = function(start, end, duration) {
console.log(this);
var _this = this;
var fakeDiv = $("<div />");
_this.promise().done(function(){
_this.animate({"a":end},{duration:duration});
fakeDiv.css("height", start).animate({
height: end
}, {
duration: duration,
step: function(now) {
_this.css("transform", "rotate(" + now + "deg)");
},
complete: function() {
fakeDiv.remove();
}
});
});
return _this;
};
var red = $('.red');
red.click(function() {
if ( !$(this).is(':animated') ) {
red.rotate(45,135,500);
setTimeout(function(){
red.rotate(135,190,500);
},750);
setTimeout(function(){
red.rotate(190,45,500);
},1500);
}
});
});
Kevin is corect, almost. :)
Here is working jsFiddle.
You don't have to use another element and height, you can do something like:
var red = $('.red'),
max_rot = 45,
start_from = 90;
red.css({a:0}).animate(
{'a':1},
{ step: function(value,tweenEvent)
{
rotateVal = start_from + max_rot * value;
red.css({
'transform':'rotate('+rotateVal+'deg)',
});
}
},
1000);​
The ideea is simple. First we create a bogus css property 'a' and set it to 0, and then we animate it to 1, so the step function will give you a value of 0 to 1 that you can use to set the custom transform.
An alternative method would be to use jQuery to change the dom to something that css would respond to.
We can set our css to look like this:
.object {
-webkit-transition:all .4s;
-moz-transform:all .4s;
-o-transform:all .4s;
-ms-transform:all .4s;
transform:all .4s;
}
.object[data-rotate="false"] {
-webkit-transform:rotate(0deg);
-moz-transform:rotate(0deg);
-o-transform:rotate(0deg);
-ms-transform:rotate(0deg);
transform:rotate(0deg);
}
.object[data-rotate="true"] {
-webkit-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-o-transform:rotate(90deg);
-ms-transform:rotate(90deg);
transform:rotate(90deg);
}
Our jQuery would look like this:
$('#trigger').live('click',function(){
if($('.object').attr('data-rotate') = true) {
$('.object').attr('data-rotate',false);
}
else {
$('.object').attr('data-rotate', true);
}
});
Obviously, the browser has to support the ability to transform whatever animation you want to run, so its its hit or miss depending on the type of animation, but its nicer to work with if you have a ton of stuff going on or you have some children you want to animate concurrently.
Example fiddle:
http://jsfiddle.net/ddhboy/9DHDy/1/

How to track element movement and trigger function at specific spot?

I have a #ball that when clicked uses jquery animate to move down 210px using this code:
$('#ball').click(function() {
$(this).animate({
top: '+=210px'
}, 500);
setTimeout(crack, 400);
});​
currently Im using Timeout to trigger the next function which is "crack".
Instead I want to track the movement of #ball and when its css top = 210px I want to trigger the function crack(), how can I do this?
I saw in a somewhat similar post that the Step function might be what I'm looking for, but I am not sure how to approach that solution based on the info provided at http://api.jquery.com/animate/
Look at Demo: http://jsfiddle.net/EnigmaMaster/hbvev/4/
I am not sure why you want to use a tracker if you know that the ball will reach the box in 210px.
If you want to get rid of setTimeout, then use the .animate callback function which will be called when the ball reaches the box.
$('#ball').click(function() {
$(this).animate({
top: '+=210px'
}, 500, crack); //<== crack will be called after ball animation
});​
DEMO
Incase if you want to call crack when the ball touches the box and still continue the movement of box then you can execute it 2 steps like below,
$('#ball').click(function() {
$(this).animate({
top: '+=180px'
}, 400, function() {
crack();
$(this).animate({
top: '+=30px'
}, 100);
});
});
Also check this version for fun in slow motion http://jsfiddle.net/skram/hbvev/8/
If you truly want to do something based on the position of the ball, then yes, step is probably the best way to go:
$('#ball').click(function() {
$(this).animate({
top: '+=210px'
}, {
duration: 500,
step: function() {
if($(this).offset().top > 208) {
crack();
}
}
});
});
Demo: http://jsfiddle.net/qJjnN/1/
Now, there are a couple of caveats:
There will be a possible performance hit.
The position at each step will not necessarily be a whole number, and the object will not exist at every pixel between the start and stop location.
step is not called on the final position, so you cannot actually check for 210 if it is the final location.
Taking those into mind, you will not be able to check for the exact position of 210px. Instead, you will want to watch when it passes a certain position and only trigger crack at that point and not every point after:
$('#ball').click(function() {
var cracked = false;
$(this).animate({
top: '+=210px'
}, {
duration: 500,
step: function() {
if($(this).offset().top > 208 && !cracked) {
cracked = true;
crack();
}
}
});
});
Demo: http://jsfiddle.net/qJjnN/2/
The step function also has parameters now and fx that can be used to see the current value of the css being animated. step is called for each step of each css attribute being animated. So, you have to be careful using those, because you need to look at fx to see what attribute value you are looking at (if you are animating more than one, i.e. top and left).
$('#ball').click(function() {
var cracked = false;
$(this).animate({
top: '+=210px'
}, {
duration: 500,
step: function(now, fx) {
if(fx.prop != 'top') {
return;
}
if(now > 208 && !cracked) {
cracked = true;
crack();
}
}
});
});

Partially showing/hiding an element with jQuery

I have this basic script that makes an element show onmouseenter, and hide onmouseleave.
In HTML version works fine, but i need to display it in wordpress; but in WP didn't work.
Firebug shows the following error:
sidebar_animate is not defined
How can I fix this?
The script
<script language="javascript">
function sidebar_animate(px) {
$('#sidebar').animate({
'marginLeft' : px
});
}
</script>
Body
<div id="sidebar" onmouseenter="sidebar_animate('+180px');"
onmouseleave="sidebar_animate('-20px');"
style="background-color: red; width: 240px; height: 100px; position: absolute; left: -180px;" >
This is going to move
</div>
How about binding the event handlers with jQuery so your code is all in one spot:
<script language="javascript">
//wait for document.ready to fire so elements are available to manipulate
$(function () {
//setup object to convert the type of event fired to the pixel offset to apply for the event
var eventToPx = {
mouseenter : 180,
mouseleave : -20
};
//bind an event handler to the `#sidebar` element for `mouseleave` and `mouseenter`
$('#sidebar').on('mouseenter mouseleave', function (event) {
//animate this element's `margin-left` property to the specified number of pixels
//note that jQuery assumes pixels if you omit units
$(this).stop().animate({
marginLeft : eventToPx[event.type]
}, 500);
});
});
</script>
Here is a demo: http://jsfiddle.net/jasper/mYwqE/
Notice that I added .stop() to your code just before the .animate() call. It will stop the current animation if a new one is queued, so the animations won't queue-up if the user mouse-over's and mouse-out's the element many times rapidly.
Note that .on() is new as of jQuery 1.7 and in this case is the same as using .bind(): http://api.jquery.com/on

how to remove a method with a callback or otherwise

I have the following code that animates an object with a delay of 800 ms:
$('#navMenu').mousemove(function (e) {
thisX = e.pageX
if (thisX >= 1625) {
$('#prbBtnHolder').animate({ left: '-=150' }, 300).delay(800);
}
});
If the #prbBtnHolder has a certain css left property i want to be able to remove the delay()method and stop the animation. How do i do this? This is what I've tried so far:
//...
$('#prbBtnHolder').animate({ left: '-=150' }, 300).delay(800);
if ($('#prbBtnHolder').css('left') < -100) {
$(this).animate({left: '-=0px'});
}
But this does not remove the delay method nor does it achieve the desired effect. Any other ideas?
In order to clear the effects queue, you'll need to use the step callback to see if your condition is met.
http://api.jquery.com/animate/
$('#prbBtnHolder').animate({
left: '-=150'
},
{
duration: 300,
step: function(now, fx) {
if (now < -100) {
// uncomment and you'll see the next animation
$(fx.elem).clearQueue().stop();
}
}
}).delay(800).animate({ width: '200px', height: '200px' }, 300);
Here is a jsbin example:
http://jsbin.com/utejew/3
$(this).clearQueue();
jQuery Docs for clearQueue
Removes all elements in the effect Queue for the given Element. Otherwise you could use js native setTimeoutfunction to animate which can easily be cleared with clearTimeout.
Before you Animate $('#prbBtnHolder') you can calculate how far the Button is away from -100 and animate it only that far.

Categories