6

I started writing some JS code to cause a variables value to increase over time, up to a target value, with some form of 'ease-in'.

I realised that jquery already does this in it's .animate() method. Of course, the method is for manipulating CSS properties, not general variables.

My question is, is there anything that can be done to hack it so that the method affects a variable, rather than a CSS property?

UpTheCreek
  • 31,444
  • 34
  • 152
  • 221
  • 1
    Can't you achieve the same effect fairly easily using `setTimeout()` directly? – nnnnnn Feb 17 '12 at 06:57
  • 2
    Animate a variable with easeIn??? That makes no sense. – elclanrs Feb 17 '12 at 06:57
  • Can you use a CSS property as your variable? In other words, don't initialize an ordinary javascript variable. Instead, make a non-displaying div or such, and where your code needs to access the variable, have it access the css property of the div instead. – John Pick Feb 17 '12 at 06:59
  • @JohnPick - yes, I was thinking about that, but it seems a little hacky. – UpTheCreek Feb 17 '12 at 07:09
  • @elclanrs - I never said 'animate a variable'. I'm talking about having the animate() method manipulate a variable over time, rather than a css property (which is just another number). – UpTheCreek Feb 17 '12 at 07:10
  • @nnnnnn, /elclanrs - yes I could, I started down that direction, but would like to re-use the jquery logic if possible. – UpTheCreek Feb 17 '12 at 07:12
  • `animate()` is only meant for css properties, as you said. I suggest as others said that you do it with `setInverval/setTimeout`. – elclanrs Feb 17 '12 at 07:17

1 Answers1

31

Yes, you can animate variables. Demo here

$({ n: 0 }).animate({ n: 10}, {
    duration: 1000,
    step: function(now, fx) {
        $("div").append(now + "<br />");
    }
});

In this example, I am animating n from 0 to 10 in 1 second. The step function is called during animation and from there you can retrieve the current value in now.

Personally, I used this technique to animate several css properties simultaneously in a non linear fashion.

Animate runs by modifying the value of properties declared in JS objects. Although animate is designed to change CSS scalar values, it can also safely be used for any generic property, as long value is a scalar one.
In fact, you can think of CSS as a set of JS objects, where properties are for example, top, margin etc.

Note that the following scripts do the same. They change CSS left from 0 to 10

$("#test").css('left', 0).animate({ left: 10 }, 1000);

is the same as

$({ left: 0 }).animate({ left: 10 }, {duration: 1000, step: function(now, fx) {
  $("#test").css('left', now);
}});

or, without using the now parameter

var obj = { left: 0 };
$(obj).animate({ left: 10 }, {duration: 1000, step: function() {
      $("#test").css('left', obj.left);
}});

To see them in action click here

Jose Rui Santos
  • 15,009
  • 9
  • 58
  • 71
  • Watch out for properties named like certain CSS attributes, such as `zoom`, `padding`, etc. jQuery tries to manipulate such properties as CSS, which obviously fails on a non-DOM object. A simple workaround is to prepend special names with a "_", so you'd animate `_zoom` instead of `zoom`. – blade Oct 13 '15 at 13:09
  • @81403 That's not true. If you run `.animate` on a non-DOM object, jQuery only sees that object and will not apply any CSS to it. [Here](http://jsfiddle.net/29Lobqg3/) I am animating a JS object with a `top` property and you can see that it doesn't move down. – Jose Rui Santos Oct 13 '15 at 14:56
  • @JoseRuiSantos How would you expect a javascript object to move down? :) Anyway, I didn't say all CSS attributes, just _some_. While `top` is working, `zoom` isn't, this should illustrate what I mean more clearly: http://jsfiddle.net/Le44kax5/ – blade Oct 14 '15 at 08:51
  • @81403 My bad. Yes, you are right. Thanks for pointing out this issue. – Jose Rui Santos Oct 14 '15 at 10:17