Плавная анимация @keyframes в Safari идет дискретно - PullRequest
0 голосов
/ 01 октября 2019

Я создал экран предварительной загрузки для веб-сайта с панелью загрузки, анимированной с помощью CSS @keyframes. Прекрасно работает на Chrome и Firefox, но на MacOS Safari становится очень дискретным. Вот видео-демонстрация того, как это выглядит в Safari: https://www.youtube.com/watch?v=ODV5lN2xZSI&feature=youtu.be

Как видите, загрузка полосы бара (серая линия) и самой полосы (черная линия) дергаются вместо плавного движения с шириной 0%до 100%. В чем может быть проблема, это известная ошибка Safari? Последние версии MacOS и Safari.

@keyframes loading-wrapper-anim {
  0% {
    width:0%;
  }

  100% {
    width:100%;
  }
}


.preloader .loading_wrapper {
  position:absolute;
  width:0%;
  height:1px;
  background:#dbdbdb;
  top:12rem;
  animation: loading-wrapper-anim 1s;
  animation-delay: 1s;
  animation-fill-mode: forwards;
  align-self:flex-start; /*this one is because of the parent element*/
}


.preloader .loading_wrapper .loading_bar {
  height:100%;
  width:0%;
  height:100%;
  background:#000;
  animation: loading-wrapper-anim 3s;
  animation-delay: 2s;
  animation-fill-mode: forwards;
}
<div class="preloader">
<div class="loading_wrapper">
    <div class="loading_bar">
    </div>
</div>
</div>

Ожидается плавная анимация.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 08 октября 2019

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

@keyframes loading-wrapper-anim {
  0% {
    transform:scaleX(0);
  }

  100% {
    transform:scaleX(1);
  }
}


.preloader .loading_wrapper {
  position:absolute;
  width:100%;
  height:1px;
  background:#dbdbdb;
  top:12rem;
  animation: loading-wrapper-anim 1s;
  animation-delay: 1s;
  animation-fill-mode: forwards;
  align-self:flex-start; /*this one is because of the parent element*/
  transform:scaleX(0);
  transform-origin:0% 0%;
}


.preloader .loading_wrapper .loading_bar {
  height:100%;
  width:100%;
  height:100%;
  background:#000;
  animation: loading-wrapper-anim 3s;
  animation-delay: 2s;
  animation-fill-mode: forwards;
  transform:scaleX(0);
  transform-origin:0% 0%;
}

Я использовал transform:scaleX() в сочетании сtransform-origin:0% 0% (это устанавливает центр преобразования в верхний левый угол), чтобы эмулировать изменение ширины, фактически не изменяя его.

Вывод: используйте transform где / когда это возможно. Они более эффективны с точки зрения CSS-анимации и переходов.

0 голосов
/ 01 октября 2019

Вы можете попытаться форсировать аппаратное ускорение, добавив translateZ к анимации.

.preloader .loading_wrapper {
  position:absolute;
  width:0%;
  height:1px;
  background:#dbdbdb;
  top:12rem;
  animation: loading-wrapper-anim 1s;
  animation-delay: 1s;
  animation-fill-mode: forwards;
  align-self:flex-start; 
  /* Add this */
  -webkit-transform: translateZ(0);
}

JSFiddle

Кроме того, вы можете использовать метод will-change в качестве последнего средства для более плавной анимации. https://developer.mozilla.org/en-US/docs/Web/CSS/will-change

...