Jerky прервал переходы CSS с помощью ngAnimate в Chrome

Я заметил, что с ngAnimate загруженными переходами CSS «дергаются» в Chrome, когда они прерываются другим переходом. То есть они как бы переходят к целевому состоянию, а не начинают с текущего значения. Точно такие же переходы намного более плавные без загруженного ngAnimate и более плавные в Firefox с/без ngAnimate.

Например, простой элемент, который добавляет/удаляет класс по клику:

<bigger-on-click-class class="{{showBigger ? 'bigger' : ''}}" ng-click="showBigger = !showBigger"></bigger-on-click-class>

анимированные переходом CSS:

bigger-on-click-class {
  display: block;
  height: 200px;
  width: 200px;
  background: red;
  -webkit-transition: height 5s;
  transition: height 5s;
}

bigger-on-click-class.bigger {
  height: 400px;
}

ведет себя по-разному при нескольких щелчках в быстрой последовательности, в зависимости от того, загружен ли ngAnimate:

http://plnkr.co/edit/Fhwbd3WRiz5wHRIm10y3?p=preview без ngAnimate http://plnkr.co/edit/WSED064MV2dtPnsEQuti?p=preview с ngAnimate

Если вы попробуете несколько раз быстро щелкнуть красные поля в предыдущих примерах, вы поймете, что я имею в виду, или щелкните ниже, чтобы просмотреть скринкаст.

asdffsda

Есть ли способ избежать этого, кроме как не загружать ngAnimate, чтобы прерывание анимации начиналось с текущего отображаемого значения/позиции?

Изменить: первоначальные ссылки были неверными. Также дерганое поведение наблюдается в Chrome, но не в Firefox. Изменить: переформулировал вопрос, чтобы было понятнее разница между Chrome и Firefox.


person Michal Charemza    schedule 18.04.2014    source источник
comment
Какое устройство вы используете?   -  person Nix    schedule 18.04.2014
comment
Я использую Chrome на Mac.   -  person Michal Charemza    schedule 18.04.2014
comment
Я этого не вижу. Я использую Chrome/Mac.   -  person Nix    schedule 18.04.2014
comment
Вы пытались использовать ng-class={'bigger': showBigger} вместо привязки текста внутри атрибута класса?   -  person Brocco    schedule 18.04.2014
comment
Я только что понял: я случайно дважды опубликовал один и тот же Plunkr. У одного из них не должен быть загружен ngAnimate, а у другого должен. Может отредактировать через час или около того (или кто-то другой, не стесняйтесь...)   -  person Michal Charemza    schedule 18.04.2014
comment
Ссылки были исправлены, а также некоторые полусломанные CSS. Я также заметил, что поведение дерганной анимации не происходит в Firefox.   -  person Michal Charemza    schedule 18.04.2014
comment
comment
Основываясь на временной шкале/кадрах инструментов chrome dev, эта анимация НАМНОГО выше 60 кадров в секунду на протяжении всей анимации. Вы перемещаетесь на 200 пикселей за 5 секунд, что является небольшим расстоянием за долгое время, а пиксели очень велики. Также я действительно не заметил никаких рывков во время анимации (Chrome v34)   -  person Brocco    schedule 28.04.2014
comment
@Brocco рывки видны, когда переход прерывается. В моих примерах, нажав еще раз на поле.   -  person Michal Charemza    schedule 28.04.2014


Ответы (3)


Я заметил, что когда происходит анимация, устанавливается стиль:

transition: none;
-webkit-transition: none;

Я предполагаю, что ngAnimate устанавливает эти свойства стиля во время его обработки, и другие браузеры не влияют на них в течение короткого момента, когда они установлены, но когда хром их видит, он немедленно завершает анимацию, как будто переход не применялся.

Итак, чтобы решить вашу проблему, вам просто нужно убедиться, что эти свойства игнорируются, установив ваши свойства как !important:

transition: height 5s !important;
-webkit-transition: height 5s !important;

Который можно увидеть работающим в plnkr здесь

person Theo    schedule 28.04.2014
comment
Спасибо! Хотя установка перехода на none кажется довольно преднамеренной. Знаете ли вы, почему это может быть, или каковы последствия установки !important на переходах, чтобы переопределить это? - person Michal Charemza; 28.04.2014
comment
Ты делаешь доброе дело. Я просмотрел исходный код и не увидел очевидных причин, по которым они это сделали. Возможно, они просто хотели, чтобы каждая анимация всегда начиналась с самого начала. Я не могу себе представить, что установка !important при переходе будет иметь какие-либо значимые последствия. Если вас это беспокоит, вы всегда можете использовать анимацию вместо перехода. - person Theo; 28.04.2014

Один из способов избежать рывков: перейти на Angular 1.3. Чтобы процитировать документы Angular 1.3 beta 7 ngAnimate

В более ранних версиях ngAnimate естественные переходы CSS могли прерываться и неправильно отображаться из-за того, что переменная $animate временно блокировала переходы с использованием 0s none.

И разницу можно увидеть в моем Plunker, использующем Angular 1.3 beta 7.

person Michal Charemza    schedule 28.04.2014
comment
Это лучший ответ, потому что более старые бета-версии Angular 1.3 не только вызывали прерывистую анимацию, но и вызывали некоторые странные проблемы с отрисовкой в ​​определенных сценариях. - person David Myers; 23.05.2014

В моем случае проблема заключалась в том, что класс ng-hide css был настроен на отображение: нет, и анимация не работала в хроме, но работает в сафари.

person RobertKru    schedule 20.05.2015