requestAnimationFrame是否会干扰CSS过渡?

时间:2019-09-20 11:34:06

标签: javascript css mapbox-gl-js requestanimationframe

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; }
  }

只要不调用requestAnimationFrame或停止发出请求,CSS动画就可以正常工作。

此外,调用requestAnimationFrame还会阻止其他过渡(这些过渡不在动画容器的范围内)起作用,例如导航抽屉,我将其用作侧面菜单。

作为导航抽屉的一项工作,我必须将请求包装如下:

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

内部setTimeout用于延迟下一个动画以使抽屉滑入。

但是,这对容器动画没有帮助。每当绘制新框架时,CSS动画就会开始并随每个新框架重置,因此动画会闪烁。

编辑:

为什么要使用requestAnimationFrame和CSS动画?

requestAnimationFrame用于插值地图上标记的坐标。地图根据画布计算X和Y的实际位置。然后使用CSS动画对该标记进行动画处理。

1 个答案:

答案 0 :(得分:2)

代码中的问题原因与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);
相关问题