从 JS 动态添加 CSS 关键帧以增加动画的随机性

Dynamically adding CSS keyframe from JS to add randomness to animation

为了帮助我的 JS 新手之旅,我正在尝试制作一个简单的游戏 - 其中有 'rubbish' (divs) 的片段从右向左漂浮在河中,然后当玩家点击 div 它会消失。

我一直在尝试为动画添加随机性,所以每块垃圾都会走不同的路径。

我希望有一种方法可以将随机值传递到关键帧动画的 'top' 百分比中,就像这样 - 有什么想法可以对其进行调整吗?我不介意将所有动画放入 JS

const btnRubbish = document.querySelector('div.smallrubbish')
const x = (Math.random() * 100)

btnRubbish.style.transform = 
    `@keyframes rubbish {
   0%  {top: ${x}%; left: 100%;}
  50%  {top: ${x}%; left: 50%;}
 100%  {top: ${x}%; left: 0%;}`

HTML

<div class="game box"> 
<div class="smallrubbish"></div> 
</div>

相关CSS

div.smallrubbish {
  display: block;
  height: 50px;
  width: 50px;
  background-color: rgba(255, 124, 0, 1);
  border-radius: 100%;
  position: absolute;
  top: 50%;
  left: 100%;
  animation-name: rubbishflow;
  animation-duration: 8s;
  animation-timing-function: linear;
  animation-iteration-count: 1;
  animation-delay: 0s;
  animation-fill-mode: forwards;
}

@keyframes rubbishflow {
   0%  {top: 50%; left: 100%;}
  50%  {top: 25%; left: 50%;}
 100%  {top: 60%; left: 0%;}
}

基本问题是如何为 CSS 动画随机创建关键帧并在运行时加载它们。

无法将@keyframes 定义内嵌添加到元素中。但是你可以通过

更改元素的动画名称
el.style.animationName = 'animation'

并且您可以在运行时将样式元素添加到您的文档头部。以问题中给出的简单示例为例,这里有一个片段,用于向动画添加随机 y 值,并为该动画提供一段垃圾:

const head = document.getElementsByTagName('head')[0];
const btnRubbish = document.querySelector('div.smallrubbish');

let keyframes = 
    `@keyframes rubbish {
   0%  {top:` + (Math.random() * 100) + `%; left: 100%;}
  50%  {top:` + (Math.random() * 100) + `%; left: 50%;}
 100%  {top:` + (Math.random() * 100) + `%; left: 0%;}`;
 
let style= document.createElement('STYLE');
style.innerHTML = keyframes;
head.appendChild(style);

btnRubbish.style.animationName = 'rubbish';
div.smallrubbish {
  display: block;
  height: 50px;
  width: 50px;
  background-color: rgba(255, 124, 0, 1);
  border-radius: 100%;
  position: absolute;
  top: 50%;
  left: 100%;
  animation-name: rubbishflow;
  animation-duration: 8s;
  animation-timing-function: linear;
  animation-iteration-count: 1;
  animation-delay: 0s;
  animation-fill-mode: forwards;
}
<div class="game box"> 
<div class="smallrubbish"></div> 
</div>

可以说在动画中创建随机数量的帧,具有随机的百分比值和随机的 x 轴位置(始终确保从右到左 - 除非你的垃圾会陷入漩涡当然)。而且每一个垃圾都可以有不同的animation-duration.

问题是如何跟踪添加的样式以及如何为每个垃圾分配新样式。这的后勤取决于游戏情况变得多么复杂 - 例如游戏是否会永远持续下去 - 在这种情况下你可能最终 运行 出 space 所以记录棋子将需要垃圾和关键帧,以便您可以重复使用它们或在不再需要时删除它们。