4

Is there a way (keeping forward-compatibility in mind) to force jQuery animations to use only integer values amidst an animation?

I'm animating an element's width.

<div style="width: 25px">...</div>

I look at the element in the inspector while it's in the middle of animating, and often the value has massive granularity decimalwise.

<div style="width: 34.24002943013px">...</div>

It only 'calms down' to integers once it's reached its goal.

<div style="width: 50px">...</div>

Usually I wouldn't bother myself about this as it's obviously functional.

However, in this project it's imperative that I stay pixel-perfect at all times, and I'm afraid using fractional pixel widths (or any other attribute measured in pixels) would render inconsistently between browsers. I know letter-spacing for one does.

Is there a way to make sure jQuery only uses decimal-free values even in the middle of animation?

EDIT: I feel like I should clarify; I'm not just using .animate({width:50}). Most of my animations are jQuery UI -powered .hide()s and .show()s, and the solution I'm looking for should obviously also work with those.

Emphram Stavanger
  • 4,158
  • 9
  • 35
  • 63
  • 1
    You could use the step callback to do this, however keep in mind that by doing so you may end up with animations that aren't as smooth as they are normally. – Kevin B Aug 22 '12 at 17:51
  • My animations are big (~1000px changes) and move fast. I doubt the change in smoothness/accuracy would be noticeable by the user. Could you demonstrate what you mean in an answer? – Emphram Stavanger Aug 22 '12 at 17:54
  • 2
    Evandro's solution does basically what mine would do, I would instead do it with a fake element similar to this answer: http://stackoverflow.com/questions/12062818/how-to-combine-jquery-animate-with-css3-properties-without-using-transitions/12062914#12062914 – Kevin B Aug 22 '12 at 17:57
  • 1
    no, you can't do it with `.hide()` and `.show()` without extending/overriding the core, it would have to be done through a custom animation with `.animate()` – Kevin B Aug 22 '12 at 17:58
  • I don't mind changing the core as long as the changes are manageable (so it'd be relatively easy to keep track of what's changed if and when the library is updated). How would that work? – Emphram Stavanger Aug 22 '12 at 18:00
  • It isn't going to be a quick easy override to make it work in all methods the way you are looking for. Best bet is to just let the animations work as-is. – Kevin B Aug 22 '12 at 18:11

2 Answers2

5

For me this worked in the right way:

$("div").animate({ width: 50}, {
    duration: 1000,
    step: function(now, fx){
        fx.now = parseInt(now);
    }
});​
vitto
  • 19,094
  • 31
  • 91
  • 130
3

Something like this?

$("div").animate({ width: 50}, {
  duration: 1000,
  step: function(now, fx){

      var value = parseInt($(this).css("width"));

     $(this).css("width", value);
  }
});​

This way, in each "frame" of the animation, the width value will be parsed into an integer value.

The animation will be less smoother this way, since you're cutting some values, but if your animation is long enough, it won't be even noticed.

Evandro Silva
  • 1,392
  • 1
  • 14
  • 29