Alexander Ziborov
Alexander Ziborov

Reputation: 21

Unable to stop CSS3 transition of transform by translate3d

I'm trying to animate an element by CSS3 transtions using translate3d: JSFiddle.

// for start animation
$("#content")
    .css("-webkit-transition", "all 100s");
    .css("-webkit-transform", "translate(0, -900px)");
// for stop animation
$("#content")
    .css("-webkit-transition", "none");

In desktop Chrome and Safari is good, but in the default browser on Android 4.1.x (SGSII, Galaxy Nexus, etc) this approach does not work - transition does not stop. Additionally, I note that the situation is only a relatively translate3d: with translate and position CSS props (e.g. "top", "left") it works.

Upvotes: 2

Views: 3346

Answers (3)

Neil Taylor
Neil Taylor

Reputation: 31

This solves my (very similar) problem:

$el.removeClass('THE_ANIMATION').css('opacity', 0.99);
window.setTimeout(function () {
  $el.css('opacity', 1); 
}, 0);

Upvotes: 0

Sani Elfishawy
Sani Elfishawy

Reputation: 663

Here is what I discovered with some experimentation:

Stopping a running translate2d or 3d on chrome, safari, firefox, and iphone webview can be done by setting a transition of "none" or a transition with a negative or 0 time delay and giving a new translation to the current position as described above.

This however does not work for android webview. The only solution I could find for android was to set the transition delay to a small positive number like .001s and giving a translate for the current position.

Note that in iphone webview the solution of a negative transition delay is preferable to "none" or a small positive number which will flash the final position of the ongoing transition before performing the preempting following transition.

Upvotes: 0

Emiel Mols
Emiel Mols

Reputation: 456

The transition implementation on Android 4 seems to be buggy in cases where a transitioning hardware-rendered layer is canceled by adjusting the webkitTransitionDuration to 0 (and setting webkitTransition to 'none' or '' often implies this). This can be circumvented by using a transition duration of .001ms or similar, although this very likely still draws multiple frames.

A more practical work-around on at least certain devices is to use a negative value for the webkitTransitionDelay, forcing a new transition to take effect, but choosing this value such that the transition starts directly in its finished state.

Like so:

e.style.webkitTransition = '-webkit-transform linear 10s';
e.style.webkitTransform = 'translate3d(100px,100px,0)';

# now cancel 10s-long transition in 1s and reset transformation
setTimeout(function() {
    e.style.webkitTransitionDelay = '-10s'
    e.style.webkitTransform = 'translate3d(0,0,0)';
}, 1000)

Upvotes: 1

Related Questions