Влияет ли requestAnimationFrame на CSS-переходы? - PullRequest
0 голосов
/ 20 сентября 2019

Возможно ли, что requestAnimationFrame не позволяет другим CSS-переходам работать?

У меня есть функция requestAnimationFrame, которая должна перемещать позицию контейнера div.Обновление выполняется при каждом запросе кадра.Контейнер div содержит CSS-анимацию:

.container {
  ...
  animation: pulse 2s infinite;
  ...
}

  @keyframes pulse {
    0%   { transform: scale(1); opacity: 1; }
    70%  { transform: scale(3); opacity: 0; }
    100% { transform: scale(1); opacity: 0; }
  }

CSS-анимация работает нормально, если я НЕ вызываю requestAnimationFrame или не прекращаю делать запросы.

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

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

this.animationId = requestAnimationFrame((timestamp) => {
  setTimeout(() => {
    this.animateContainer(timestamp)
  }, 50)
})

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

Однако для контейнера это не помогаетанимация.Всякий раз, когда рисуется новый кадр, анимация CSS начинается и сбрасывается с каждым новым кадром, поэтому анимация мерцает.

РЕДАКТИРОВАТЬ:

Почему я использую requestAnimationFrame и CSS-анимацию?

requestAnimationFrame используется для интерполяции координат маркера на карте.Фактическое положение для X и Y рассчитывается картой в зависимости от холста.Затем анимация CSS используется для анимации этого маркера.

1 Ответ

2 голосов
/ 20 сентября 2019

Причина проблемы в вашем коде не связана с requestAnimationFrame, но является функцией, которая вызывается rAF.

В animateMarker вы добавляете один и тот же маркер каждый раз requestAnimationFrame называется.Это должно быть возможно.Однако, поскольку вы хотите показать анимацию ключевых кадров CSS на маркере, она не будет работать.Это происходит потому, что каждый раз, когда вызывается marker.addTo(map), маркер быстро удаляется и повторно добавляется, а также сбрасывает анимацию ключевых кадров.

Добавление маркера на карту снаружи функции animateMarker и только меняйте положение маркера.Это предотвратит сброс маркера и даст желаемый результат.

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v11',
  center: [0, 0],
  zoom: 2
});

var el = document.createElement('div');
var dot = document.createElement('div');
dot.className = 'mapboxgl-user-location-dot';
el.appendChild(dot);

// Set radius globally.
var radius = 20;

// Add marker before animate loop.
var marker = new mapboxgl.Marker(el)
  .setLngLat(      
    Math.cos(0 / 1000) * 20,
    Math.sin(0 / 1000) * 20
  ]);
  .addTo(map);

// Change only the position in the animation loop without re-adding the marker.
function animateMarker(timestamp) {

  // Update the data to a new position based on the animation timestamp. The
  // divisor in the expression `timestamp / 1000` controls the animation speed.
  marker.setLngLat([
    Math.cos(timestamp / 1000) * radius,
    Math.sin(timestamp / 1000) * radius
  ]);  

  // Request the next frame of the animation.
  requestAnimationFrame(animateMarker);
}

// Start the animation.
requestAnimationFrame(animateMarker);
...