3

I'm creating an HTML5 app for iPhone to run in a UIWebview using Sencha Touch 2.

I've created several methods to help myself to css animations. One of them does translate in the Y axis for me. I've set on things like -webkit-backface-visibility in my CSS to help smooth over animations. I've tried webkit perspective and webkit preserve-3d, but they seem to not help.

Anyways, I've gotten the animations to a point where they are very smooth. The problem is, if I'm translating a large group of elements simultaneously, one of them won't translate.

Let's say I'm translating A, B, C, D, E, and F upwards. F will just skip right to the end -- no translation. It's almost as if the -webkit-transform gets set before the -webkit-transition-duration, which is not what's happening in my code. Furthermore, A, B, C, D, and E animation perfectly.

I'm not even sure if this is exclusive to when I'm animating a large group of elements, but that seems to be how it is happening now. If it happens to F, it will always happen to F -- so it is at least consistent in that sense.

I even tried to fix it by dynamically creating a element with a new class style equal to the transform and duration, embedding that in the DOM, and then setting the element's class equal to the class of the style. I got the same problem.

The thing is, if I embed the final line of Animations.translateY in a setTimeout function, even for 1 millisecond delay, the everything will always animate. This, however, leads to the screen flickering nastily ~33% of the time, which I'm guessing is due to too many setTimeouts?

As for browser consistency, I see the lack of animation (without setTimeout) in both chrome on my PC and the UIWebview on the iPhone device. I only see flicker (with setTimeout) on the iPhone device.

Animations.translateY = function(element, measurement, duration, callback, easing)
{
    Animations.setAnimationCallback(element,callback)

    var css = "translate3d(0,"+measurement+",0)"; 
duration = parseFloat(duration);
element.style['-webkit-transition-duration'] = duration + 's';
    element.style['-webkit-transform'] = css
}

the animation callback code.. I feel this is irrelevant, because the callback never actually fires (animations that take 0s don't fire a callback)

Animations.setAnimationCallback = function(element, callback)
{
    //set callback handler
    element.addEventListener('webkitTransitionEnd', 
            function(){
                //set animation duration back to 0
                this.style['-webkit-transition-duration'] = "0s";
                if(callback != null)
                {
                    callback();
                }
                this.removeEventListener('webkitTransitionEnd', arguments.callee, null);
            });
}
marklar
  • 502
  • 7
  • 21
  • Not really a solution, but you could try [double buffering](http://stackoverflow.com/questions/2795269/does-html5-canvas-support-double-buffering) and see if it removes the flickering. – Cavyn VonDeylen Aug 21 '12 at 18:08
  • That's a cool thought, but I'm not using the Canvas, I'm just animation in the DOM. If I tried to replicate what that thread is doing but for the DOM, I'm worried that would bloat the DOM and lead to choppy animations – marklar Aug 22 '12 at 04:44
  • Is it always "F" regardless of order (among A,B...), or always the 6th one, or always the last one that has an issue? – Erik Eidt Aug 24 '12 at 22:07
  • Also, have you tried putting display:"none"/display:"" (or visibility:"hidden"/"") surrounding the pair of .style[] attribute updates? With other things, sometimes I've found that either hiding them before making some changes then reveal helps, or, hiding them all, then making all changes, then reveal them all. And still one more thought, sometimes making all changes of one sort then all changes of another sort can help, e.g. set all .style[-duration] first, then set all .style[-transform] after. Just some thoughts.. – Erik Eidt Aug 24 '12 at 22:09
  • It's pretty consistent in which one it happens to, but it isn't clear what the threshold is before flickering begins, since sometimes it can be just a few elements causes a flicker and other times 10 does. As for your second suggestion, it is a good one -- it avoids reflows, right? It would just cause a considerable rewrite of the code, and we be sort of funky, because the animations would all need to be setup before any of them ran, as opposed to doing it on a one-by-one basis. – marklar Aug 30 '12 at 21:34

1 Answers1

5

it seems to work in this: http://jsfiddle.net/cuzzea/9WGGf/ I just changed in your function:

 "translate3d(0,"+measurement+",0)"

to

 "translate3d(0,"+measurement+"px,0)"

Without the measurement("px") it did not work.

cuzzea
  • 1,515
  • 11
  • 22
  • Thanks, but I actually left the function like that so other measurement units, such as % and em, could be used in addition to pixels. Keep in mind here, the issue is not that it doesn't work -- it's that after a a few animations fire at the same time, there are performance issues. – marklar Aug 30 '12 at 21:31