Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 animation flicker on Android 2.2 (webkit-transform:translate(..) scale(..) at the same time)

I did some research on Android about CSS3 animation (transformation with webkit-transition). The CSS3 animation is still an experimental feature in Webkit. If you try to do translation and scaling at the same time, you'll find a few glitches and/or bugs in the CSS Animation (for example, see http://www.youtube.com/watch?v=vZdBVzN1B8Y ). In other words, in many versions of Android the property -webkit-transform:matrix(...) does not work correctly. The only correct way to get scaling and translation at the same time is to set "-webkit-transform:scale(...) translate(...)" in this order. I'll shere my results at the bottom of this post.

As you can see in it, I have overcome most of them. However, there's still some `flicker' in some transition on Android 2.2 (Froyo).

Now my question: is there any way to do scaling and translation at the same time without flicker on Android 2.2?

I've also tried -webkit-backface-visibility:hidden;, -webkit-perspective:1000; and -webkit-transform:translate3d(..,0) but these properties introduce some glitch in the transition. You can see it in the following video: http://www.youtube.com/watch?v=Aplk-m8WRUE The scaling is canceled after the transition stops.

Is there any other workaround to suppress flicker? Any ideas?


The below is my results about CSS3 transition on Android (1.5 <= ver <= 2.2). It employs scaling and translation at the same time on the blue box.

<html>
<head>
 <title>css3test</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
 <meta name="viewport" content="width=device-width">
</head>
<body>
<div id='log'></div>
<div id='box' style="background-color: blue; width:100; height:100;"></div>
<script language='JavaScript'>
function mesg(str) {
  document.getElementById('log').innerHTML = str;
}
var e = document.getElementById('box');
e.style['-webkit-transition-property'] = '-webkit-transform';
e.style['-webkit-transform-origin'] = "0 0";
e.style['-webkit-transition-duration'] = '350ms';
e.style['-webkit-transition-timing-function'] = 'linear';

// These properties will suppress flicker, but spoiles scaling on Android 2.2 ...
// see http://www.youtube.com/watch?v=Aplk-m8WRUE
e.style['-webkit-backface-visibility'] = 'hidden'; 
e.style['-webkit-perspective'] = '1000';

var b = 0;
function doAnim() {
  var trans;
  switch(b){
  case 0: // step 0. translate and scale at the same time
    // 1) matrix
    // On Android 1.5, we get no translation, but the box is only enlarged. Broken.
    // On Android 2.2, the transition does not occur but the box moves instantly.
    //trans = 'matrix(2,0,0,2,100,100)';
    // 2) scale first, then translate
    // On Androi2.2, there's some glitches.
    //trans = 'scale(2,2) translate(50px,50px)'; 
    // 3) tranlate first, then scale -- CORRECT 
    trans = 'translate(100px,100px) scale(2,2)';
    break;
  case 1: // step 1. translate
    // 1) matrix 
    //trans = 'matrix(1,0,0,1,35,35)';
    // 2) translate only -- will spoil transition -- 
    // On Android 1.5, the transition corrupts and the box repeatedly moves in a wrong direction. Bug?
    // see http://www.youtube.com/watch?v=vZdBVzN1B8Y
    //trans = 'translate(35px,35px)';
    // 3) tranlate first, then scale with (1,1) -- CORRECT 
    trans = 'translate(35px,35px) scale(1,1)';
    break;
  case 2: // step 2. scaling
    // 1) matrix -- nope.
    //trans = 'matrix(1.4,0,0,1.4,0,0)';
    // 2) scale only -- will spoil transition --
    //trans = 'scale(1.4,1.4)';
    // 3) tranlate with (0px,0ox), then scale -- CORRECT 
    trans = 'translate(0px,0px) scale(1.4,1.4)';
    break;
  case 3: // step 3. again, translate and scale at the same time
    // 1) matrix -- nope.
    //trans = 'matrix(1.2,0,0,1.2,100,100)';
    // 2) scale then translate -- will spoil transition --
    //trans = 'scale(1.2,1.2) translate(83.33px,83.33px)';
    // 3) tranlate first, then scale -- CORRECT 
    trans = 'translate(100px,100px) scale(1.2,1.2)';
    break;
  }
  e.style['-webkit-transform'] = trans;
  mesg('move '+b+'<br/>transform:'+trans);

  b=(b+1)%4;
}
var isAndroid = (new RegExp("android","gi")).test(navigator.appVersion);
if(isAndroid) {
  e.addEventListener('touchstart', doAnim, false);
} else {
  e.addEventListener('mousedown', doAnim, false);
}
document.addEventListener('touchmove', function(e){ e.preventDefault(); }, false);
</script>
</body>
</html>
like image 631
Keigo Imai Avatar asked Nov 24 '10 18:11

Keigo Imai


2 Answers

it's an open bug. star it to vote for it to be fixed asap.:

http://code.google.com/p/android/issues/detail?id=12451

like image 71
Nadav Avatar answered Nov 06 '22 23:11

Nadav


In most cases the flickering is caused by nested elements who are being animated. Reduce the amount of nested elements, could be hard in some cases, but it helps most of the times.

like image 38
Barry Avatar answered Nov 06 '22 22:11

Barry