CSS3 анимация-заливка-режим polyfill

предисловие

давайте притворимся, что a div анимированные с opacity:0; to opacity:1; и я хочу сохранить opacity:1; после окончания анимации.

что это animation-fill-mode:forwards; делает.

@keyframes myAnimation {
    from { opacity:0; }
    to { opacity:1; }
}
div {
    opacity:0;
    animation-name:myAnimation;
    animation-delay:1s;
    animation-duration:2s;
    animation-fill-mode:forwards;
}​
<div>just a test</div>​

запустите его на jsFiddle

  • Примечание 1: я не включил префиксы поставщика здесь, чтобы упростить
  • примечание 2: это всего лишь пример, пожалуйста, не отвечайте "просто используйте функцию jQuery fadeIn" так далее.

некоторые вещи, чтобы знать

на ответ я читал, что animation-fill-mode поддерживается Chrome 16+, Safari 4+, Firefox 5+.

но animation только поддерживает Chrome 1+ и Opera тоже. Итак, Общий тест с Modernizr может вернуться положительным, даже если fill-mode не поддерживается.

на цели animation-fill-mode я добавил новый тест на Modernizr:

Modernizr.addTest('animation-fill-mode',function(){
    return Modernizr.testAllProps('animationFillMode');
});

теперь у меня .no-animation-fill-mode класс для CSS и Modernizr.animationFillMode для JavaScript.

я также читаю из CSS3 анимация спецификации что:

анимация, указанная в таблице стилей документа, начнется с загрузка документов


и, наконец, вопрос(ы)

можно ли запустить простую функцию jQuery в точное количество секунд анимация заканчивается

$(document).ready(function(){
    if(!Modernizr.animation){
        $('div').delay(1000).fadeIn(2000);
    }else if(!Modernizr.animationFillMode){
        $('div').delay(3000).show();
    }
});

и в CSS:

.no-animation-fill-mode div {
    animation-iteration-count:1;
}
/* or just animation:myAnimation 2s 1s 1; for everyone */

или есть какой-либо известный polyfill конкретные на animation-fill-mode ?


кроме того, что произойдет, если я использую сокращенный синтаксис

animation:myAnimation 2s 1s forwards;

в браузерах, поддерживающих animation а не animation-fill-mode ?

Спасибо большое!

3 ответов


Если бы это был я, я бы попробовал выбрать более простую альтернативу-если это возможно. Я бы понизил свою реализацию, чтобы я использовал только то, что принято. Позже, когда эта функция будет более широко поддерживаться, я подумаю о ее реализации. Я редко рассматриваю возможность использования функции, которая имеет This is an experimental technology трансляция на страницах документации - но тогда, возможно, я должен быть классифицирован как скучный :)

в вашем примере вы можете достичь того же результата, что и animation-fill-mode:forwards путем определения конечного состояния ваш элемент изначально, и с помощью цепной анимации (если требуется задержка перед действием):

@keyframes waitandhide {
  from { opacity:0; }
  to { opacity:0; }
}
@keyframes show {
  from { opacity:0; }
  to { opacity:1; }
}
div {
  opacity:1;
  animation: waitandhide 2s 0s, show 2s 2s;
}
<div>just a test</div>​

http://jsfiddle.net/RMJ8s/1/

Теперь возможно, что более медленные браузеры могут мигать ваши начальные состояния элементов, прежде чем скрывать их снова. Но по моему опыту я видел это только на очень старых машинах и для страниц, которые имеют огромное количество css для рендеринга.

очевидно, что выше действительно раздувает ваш css немного больше (как вы должны дублировать стили), и это было бы сложнее при работе со сложными анимациями. Однако:

  1. он должен работать практически для любой ситуации анимации.
  2. это позволит избежать необходимости JavaScript (за исключением $().fadeIn fallback).
  3. он будет работать во всех браузерах, поддерживающих анимацию css.
  4. вы не рискуете тем, что JS и CSS будут / станут несинхронизированный.

что касается использования коротких форм, было бы лучше не делать этого, если вы хотите пойти на максимально широкую совместимость браузера. Однако, как показано в моих примерах выше, я выбрал короткие формы, потому что они содержат больше ясности, и я могу понять, что не хочу писать (или прочитать) многословные версии все время. По этой причине я бы рекомендовал использовать less для создания вашего css:

http://lesscss.org/

http://radiatingstar.com/css-keyframes-animations-with-less


Я не знаю никакой полифилл... Но я бы сказал, что вы действительно должны использовать свой собственный тест Modernizr, а для браузера, который не поддерживает режим заполнения анимации, вы должны использовать animationEnd событие, чтобы вызвать обратный вызов и установить непрозрачность 1 (или удалить класс).

посмотреть: переход событий с помощью CSS3

что касается сокращенной нотации, IE


FYI, вот как я реализую ответ pebbl (который является очень умным ответом) в настоящее время. Мне нужно только Modernizrобнаружение css-анимации.

предположим, я хочу скользить и исчезать этот div:

<div class="target">Some stuff</div>

прежде всего, я записываю анимацию С вендорных префиксов

@keyframes byebye {
    0% { height:100px; opacity:1; }
    100% { opacity:0; height:0; }
}

тогда новый класс

.target-animation {
    height:0; opacity:0; // same as "100%" state
    animation:byebye 750ms 1;
}

переезд в javascript:

// $('.whatever').on('click',function(){ ...

if(Modernizr.cssanimations)
    // css animations are supported!
    $('.target').addClass('target-animation');
else
    // i hate you IE
    $('.target').animate({height:0,opacity:0},750);

демо

Если вам нужно запустить анимацию несколько раз, просто удалите класс с javascript, как описано здесь:

// if(Modernizr.cssanimations) ...

$('target').addClass('target-animation').on('webkitAnimationEnd oAnimationEnd oanimationend animationend msAnimationEnd',function(){
    $(this).removeClass('target-animation')
    // don't forget to  .hide()  if needed
});

// ... else