21

So I've got some native elements (divs) with various effects applied to them (border-radius, box-shadow and transform: scale()). When I animate them, two weird things happen:

  1. Even though I'm not trying to animate the scale, if I don't put the scale in the animation, it is ignored.
  2. When I put the scale in the animation, Webkit blurs the elements

See the example here: http://jsfiddle.net/trolleymusic/RHeCL/ - the buttons at the bottom will trigger the issues.

The first issue happens in Firefox too, so I'm guessing that it's because that's how the animation spec is supposed to work. Not what I wanted, but ok, I'll live with it.

The second issue is just weird. I know it's to do with 3d transform because if I (just for testing purposes) declare -webkit-perspective or -webkit-transform-style: preserve-3d; on the circle elements, it causes the blur issue as well. My confusion is that I'm not trying to transform the z index as all, and I have also tried the animations using purely translateY instead of translate.

It happens in Chrome (18), Chrome Canary (20) and Safari (5.1.2 & 5.1.4).

So, am I right in what I think is happening? And how can I avoid the blurriness?

Worst-case scenario: I can just use different sizes for the elements instead of scaling them, that's not really a problem - but I thought this would be a more elegant solution and now this issue has cropped up.

alex
  • 479,566
  • 201
  • 878
  • 984
Trolleymusic
  • 2,162
  • 3
  • 19
  • 26
  • It's ignored because both scale and translate are values of the transform property. When animating, you override the previous transform, ie scale. – mddw May 02 '12 at 16:53
  • Yeah, I thought so. I guess it's just how the `transform` property works, it's a shame that you can't individually set the different properties. EG: I can animate the opacity of multiple elements with different classes which have different properties in them. – Trolleymusic May 03 '12 at 11:10

2 Answers2

18

Refer to this answer as to why it's blurring the element: https://stackoverflow.com/a/4847445/814647

Summary of the above: WebKit is taking the original size/CSS before animating, and treating it as an image, THEN scales it up, producing the blurriness.

Solution: Make initial size the largest scale you're going to, and start it initially with a lower scale (so in your case you'd want to up the size by 5, and set the initial scale to 0.2)

UPDATE

The reason it ignores the current scale from what I understand is because you're not specifically setting JUST the translate (I'm looking up the CSS for it now). When you run -webkit-animation, it's resetting all your current transforms (scale), so you need to make sure that you have your scales in there. I'm looking up the css to change so it only changes just the position:

Community
  • 1
  • 1
Josh Allen
  • 987
  • 12
  • 30
  • Thanks, yeah, I'd seen this - but the problem is that in this particular example I'm setting up multiple elements which will have the same basic structure, colours and animation, but different constant scales. So the issue remains that I would need to set each with a different initial size or create muleiple So the thing is that I can write the inital element as, say, 400x400, and then use .big and .medium to scale them down to 0.5/0.2 but then the animation will override the scale setting. So in this case I may as well set the sizes on the individual elements as opposed to using scale. – Trolleymusic May 03 '12 at 11:18
  • I'd wanted to be able to have: `div.circle.big`, `div.circle.small`, `div.circle.whatever` and have `.circle` set up the basic properties, `.big .small .whatever` set up the various sizing, and for all `.circles` to inherit the same `translateY` animation... – Trolleymusic May 03 '12 at 11:18
  • http://jsfiddle.net/trolleymusic/f7GBp/ <-- @JoshAllen : this is, **I think**, the cleanest solution I can get. What do you think. – Trolleymusic May 03 '12 at 11:28
0

The best way I found is to wait the animation is complete, then apply the transforms directly to the element and remove the animation class. Something like this works for me, producing no glitches:

$m.bindOnce($m('win-text'), 'webkitAnimationEnd', function(){ //avoid blurred problem with animating scale property in webkit
    $m('win-text').style.webkitTransform = 'scale(1.5) translateY(-60px)';
    $m.removeClass($m('win-text'), 'final');
});

I'm using a different library than jQuery, but you get the idea.

Gianluca Pinoci
  • 101
  • 3
  • 7