jquery-archive / jquery-mobile

jQuery Mobile Framework
https://jquerymobile.com
Other
9.69k stars 2.4k forks source link

Page transitions animations don't work with Firefox #1445

Closed shmerl closed 13 years ago

shmerl commented 13 years ago

Page transitions animations from http://jquerymobile.com/demos/1.0a4.1/#docs/pages/docs-transitions.html don't work properly with Firefox 4.0 (desktop and mobile). Page just switches, but no actual animation is shown.

It significantly reduces the visual appeal of the UI.

jblas commented 13 years ago

@shmerl

The transitions used within jQuery Mobile make use of CSS3 keyframes. Firefox does not support CSS3 keyframes yet, though I heard it landed in the FireFox 6 branch.

Switching over to using CSS3 transitions would require extra JS logic, specific to each transition, to make sure all properties being animated for the transition have the initial "from" values set prior to triggering the CSS transition.

toddparker commented 13 years ago

Yep, as Kin said, we're only using CSS transitions because JS animations are too slow and heavy for mobile. Closing because we're not able to make this work.

matthew-dean commented 13 years ago

"we're only using CSS transitions because JS animations are too slow and heavy for mobile." Um, thanks for crippling a feature by virtue of a personal opinion. JS animations work just fine on many mobile devices.

shmerl commented 13 years ago

Don't worry. CSS transitions are already coming in Firefox 5: http://www.h-online.com/open/news/item/Firefox-5-nears-with-release-candidate-1261711.html

jblas commented 13 years ago

Well the good news is that we've refactored the code so folks can actually write plugins to animate any way they wish:

https://github.com/jquery/jquery-mobile/wiki/Page-Transition-Plugins

This will be available in Beta 1.

matthew-dean commented 13 years ago

This is good. Frustrating because I'm using jQuery Mobile for a site that's cross-platform, cross-device. Limiting any site to "mobile-only" is a bad idea, but maybe this is a bad choice on my part. It looks like the prevalent thinking in jQuery Mobile is that "mobile" is somehow miles away from "desktop", instead of a complete continuum.

matthew-dean commented 13 years ago

@jblas: Well, now THAT is good news.

toddparker commented 13 years ago

@matthewdl - As a project, we actually do consider mobile > desktop a very fuzzy continuum which is why we support all browsers, not just mobile. CSS-based transitions already work well on many flavors of desktop Webkit and now Firefox 5 and will soon be pretty well supported. Most importantly, they tend to be hardware accelerated. We're going in that direction because they tend to be very smooth it's a a future-looking approach, not because this is mobile-focused.

If you do end up re-creating all the various transitions in JS, please do let us know and we can offer it as a plugin.

ghost commented 13 years ago

Actually, using css transitions without the keyframes is not that hard to do, especially with the new transition handler architecture.

The full js code I've used is listed below. It may not be perfect (and most of it was written for alpha4.1) but it works pretty fine in the browsers I've used for testing so far :). The css is abbreviated for demonstration and includes just the slide+in/out+reverse animation.

First, some CSS rules (missing all kind of -vendor-prefixes for brevity):

.in, .out {
  transition-timing-function: ease-in-out;
  transition-duration: 350ms;
}
.animate {
  transition-property: transform;
}
.slide.in, 
.slide.out.reverse.animate {
  transform: translateX(100%);
}

.slide.in.animate,
.slide.in.reverse.animate,
.slide.out { 
  transform: translateX(0); 
}

.slide.in.reverse, 
.slide.out.animate { 
  transform: translateX(-100%); 
}

Plus some javascript (the transition-handler is mostly copied from the jqm css3TransitionHandler):

  /**
   * jqm checks for transitions but uses it for webkit-animations...
   * */
  $.support.cssActualTransitions = "TransitionEvent" in window 
    || "WebKitTransitionEvent" in window 
    || "OTransitionEvent" in window;

  /**
   * Runs a transition on the element specified by the animation classes passed as first argument
   * (cp. jquery.mobile.transitions.css) and calls a callback once they're done.
   * 
   * If the callback event has not been triggered after <timeout> milliseconds, the callback is
   * called "manually". The optional third argument allows you to define a custom timeout or 
   * disable it completely (by passing 0 or false).
   */
  $.fn.jqmTransition = function( classes, callback, timeout ){
    if (typeof timeout == "undefined") {
      timeout = 1000;
    }
    if($.support.cssActualTransitions){
      var $this = $(this);
      var fallbackTimeout = null;
      var handler = function() {
        if (fallbackTimeout) clearTimeout(fallbackTimeout);
        var result = callback ? callback.apply(this, arguments) : undefined;
        $this.removeClass("animate " + classes);
        return result;
      };
      $this.one("transitionend webkitTransitionEnd OTransitionEnd", handler);
      if (timeout) {
        fallbackTimeout = setTimeout(handler, timeout);
      }
      // add animate class to start animation
      $this.addClass(classes);
      setTimeout(function() {
        $this.addClass("animate");
      }, 0);
      return $this;
    }
    else{
      // defer execution for consistency between webkit/non webkit
      setTimeout(callback, 0);
      return $(this);
    }
  };

  /**
   * JQM Transition handler that uses actual transitions that work in most browsers,
   * not -webkit-only animations (which are, granted, a little nicer to use).
   */
  function cssActualTransitionHandler( name, reverse, $to, $from )
  {
    var deferred = new $.Deferred(),
      reverseClass = reverse ? " reverse" : "",
      viewportClass = "ui-mobile-viewport-transitioning viewport-" + name,
      doneFunc = function() {
        $to.add( $from ).removeClass( "out in reverse " + name );
        if ( $from ) {
          $from.removeClass( $.mobile.activePageClass );
        }
        $to.parent().removeClass( viewportClass );

        deferred.resolve( name, reverse, $to, $from );
      };

    $to.parent().addClass( viewportClass );
    if ( $from ) {
      $from.jqmTransition( name + " out" + reverseClass );
    }
    $to.addClass($.mobile.activePageClass).jqmTransition(name + " in" + reverseClass, doneFunc);

    return deferred.promise();
  }

  $.mobile.defaultTransitionHandler = cssActualTransitionHandler;
scottjehl commented 13 years ago

Thanks for the code, @bfd. We'll give it a look! Maybe it'll help to try a different approach for smoothing things out in already-supporting browsers as well.

@matthewdl: Thanks for the feedback. We're working on recommendations for scaling the framework up to tablet and desktop, but so far the transitions were mostly targeted for the mobile browsers that supported them at the time we created them. Now that support has expanded, we aren't intentionally excluding any browsers from transitions, we just haven't gotten around to adding more prefixes for browsers that support our current setup (which is based on keyframes). We've had a ticket open for this for some time, and we're looking to add other prefixes soon.

That said, we're not entirely sure how our transitions should play out by default in desktop browsers yet, since many of the transitions tend to feel distracting and unnatural in that environment for simple page changes (particularly the slide transitions). Since page transitions are more common in mobile browsing than the desktop web currently, we didn't see this as a major issue for beta 1, but we're starting to work on it now. Slight tangent, but on the new docs site, we've set our transitions differently depending on window width, moving to "fade" around 600px and up, and then to "none" at 1000 and up. We may experiment with this thinking in the coming weeks, and we'd love your feedback.

Anyway, we're looking to broaden our transitions support now, ideally without adding too much bloat to the css. Maybe the suggestion above will be a good starting point to explore.

Thanks!

shmerl commented 13 years ago

More info on CSS transitions and CSS animations in Firefox and Fennec: https://developer.mozilla.org/en/CSS/CSS_animations https://developer.mozilla.org/en/CSS/CSS_transitions

shmerl commented 13 years ago

Tested with desktop Firefox 5 - the demo still doesn't work as expected it seems.

toddparker commented 13 years ago

@shmeri - We're just discussing how to implement transitions in non-Webkit browsers. We haven't implemented anything for Firefox yet. Supporting Firefox means adding a whole set of -moz prefixed rules.

shmerl commented 13 years ago

Supporting Firefox normally still makes sense, since you mention Fennec as grade A browser in support table. Fennec 5 should support transitions fully I believe.

EDIT: one will need to use -moz after all: Quote: Note: Because the CSS transitions specification is still in draft form, all properties associated with them should be prefixed with "-moz-" for use in Gecko. For compatibility with WebKit, you should also use the "-webkit-" prefix, and for Opera compatibility, use the "-o-" prefix. So, for example, you would specify the transition property as -moz-transition, -webkit-transition, and -o-transition.

But you are already using -webkit notation, so adding -moz won't hurt.

toddparker commented 13 years ago

We'll support transitions in Firefox by 1.0, but my only point is that the work isn't yet done so no need to keep testing these until we announce the tweaks :)

toddparker commented 13 years ago

Rather, we will be looking into adding these for 1.0. Guess I shouldn't announce a feature until we have time to evaluate it. At some point this will happen. Going to re-open so we can track this.

gseguin commented 13 years ago

See also issues #455 and #13

gseguin commented 13 years ago

@shmerl: The transitions branch has the latest work on this. Slide animations should work on Firefox now.

shmerl commented 13 years ago

Thanks, I tested the branch in Firefox 5, transitions work now, except for Flip.

toddparker commented 13 years ago

We've decided to not push the change to transitions until after 1.0 because browser support and performance isn't there yet. Closing for now, but will re-open when we get ready to flip the switch.

Garavani commented 10 years ago

I recently changed all my Jquery animate() features to CSS transition using the query-transit plugIn by ricostacruz.com. It is hard work and very very buggy in more complex situations especially with window resizing and so on (I had to reattach classes after each x/y transition and so on). But I do believe it is worth the effort because in effect the animations are soooo much smoother that I wonder why query animate() still exists the way it does. But also I recently saw that Firefox indeed tends to look worse with CSS transitions using keyframes (which I had to do in certain places to do easeOutBounce and such things) Only my feeling.