【问题标题】:How to get smooth transitions in pure JavaScript and CSS?如何在纯 JavaScript 和 CSS 中获得平滑过渡?
【发布时间】:2021-09-09 05:26:59
【问题描述】:

我有带有黑色背景颜色的div 元素,它们获取和释放类animated,该类具有动画彩色背景的css 定义。动画运行流畅。但是从黑色到动画状态的变化并没有。我尝试了一些过渡规则,但我不知道如何获得平滑的变化。

这是我的最小示例:

let randomNumber;
let boxes = document.querySelectorAll(".dark");
let randomNumbers = [];
let milliseconds = 2000;
setInterval(function() {
  randomNumber = Math.floor(Math.random() * boxes.length);
  randomNumbers.push(randomNumber);
  boxes[randomNumber].className = boxes[randomNumber].className.replace(/(?:^|\s)dark(?!\S)/g, " animated");
  setTimeout(function() {
    boxes[randomNumbers[0]].className = boxes[randomNumbers[0]].className.replace(/(?:^|\s)animated(?!\S)/g, " dark");
    randomNumbers.shift();
  }, boxes.length * milliseconds);
}, milliseconds);
@keyframes animated_background_color {
  0% {
    background-color: #e66000;
  }
  25% {
    background-color: #ff9500;
  }
  50% {
    background-color: #ffcb00;
  }
  75% {
    background-color: #ff9500;
  }
  100% {
    background-color: #e66000;
  }
}

.box {
  height: 20px;
  margin-bottom: 4px;
  width: 20px;
}

.dark {
  background-color: black;
}

.animated {
  animation-name: animated_background_color;
  animation-duration: 3s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  background-color: #e66000;
}
<!DOCTYPE html>

<html>

<head>
  <title>Animation</title>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head>

<body>
  <div class="box dark"></div>
  <div class="box dark"></div>
  <div class="box dark"></div>
  <div class="box dark"></div>
  <div class="box dark"></div>
</body>

</html>

【问题讨论】:

标签: javascript html css css-animations css-transitions


【解决方案1】:

根据devdgehogcomment,我决定添加更多关键帧。现在我从黑暗状态切换到动画状态,然后再次返回,第一个和最后一个关键帧设置黑暗背景,其他关键帧连续三次从橙色切换到亮橙色到黄色到亮橙色到橙色。

const DARK_SELECTOR = ".dark";
const DARK_CLASS = "dark";
const ANIMATED_CLASS = "animated";
const ANIMATION_CYCLE_TIME = 6000;

function animateRandomBox(animationTime) {
  const darkBoxes = document.querySelectorAll(DARK_SELECTOR);
  const numberOfDarkBoxes = darkBoxes.length;
  if (numberOfDarkBoxes === 0) {
    return;
  }
  const randomBoxNumber = Math.floor(Math.random() * numberOfDarkBoxes);
  const randomBoxClass = darkBoxes[randomBoxNumber].classList;
  randomBoxClass.remove('dark');
  randomBoxClass.add('animated');
  setTimeout(() => {
    randomBoxClass.add('dark');
    randomBoxClass.remove('animated');
  }, animationTime);
}

setInterval(() => animateRandomBox(ANIMATION_CYCLE_TIME), ANIMATION_CYCLE_TIME);
@keyframes animated_background_color {
  0% {
    background-color: #000;
  }
  12% {
    background-color: #ff9500;
  }
  25% {
    background-color: #ffcb00;
  }
  37% {
    background-color: #ff9500;
  }
  50% {
    background-color: #ffcb00;
  }
  62% {
    background-color: #ff9500;
  }
  75% {
    background-color: #ffcb00;
  }
  87% {
    background-color: #ff9500;
  }
  100% {
    background-color: #000;
  }
}

body {
  display: grid;
  grid-auto-rows: min-content;
  row-gap: 0.25rem;
}

.box {
  height: 1rem;
  width: 1rem;
  border-radius: 0.5rem;
}

.dark {
  background-color: black;
}

.animated {
  animation-name: animated_background_color;
  animation-duration: 6s;
  animation-timing-function: linear;
}
<!DOCTYPE html>

<html>

<head>
  <title>Animation</title>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head>

<body>
  <div class="box dark"></div>
  <div class="box dark"></div>
  <div class="box dark"></div>
  <div class="box dark"></div>
  <div class="box dark"></div>
</body>

</html>

【讨论】:

    【解决方案2】:

    你的开始和结束颜色不是黑色,这就是你看到转变的原因之一。将您的 0% 和 100% 值替换为 background-color: black;

    一旦这个问题得到解决,您的milliseconds 变量就会出现问题,因为它不是动画时间的分隔符(这里是 5*2000 毫秒,这意味着 .animated 类会在动画循环的 10 秒时删除该类是3s)


    奖励:我不知道为什么要清理和修改您的代码,但我做到了。 (我累了,很丑)

    const DARK_SELECTOR = ".dark";
    const DARK_CLASS = "dark";
    const ANIMATED_CLASS = "animated";
    const ANIMATION_CYCLE_TIME = 2000;
    const TOTAL_ANIMATION_TIME = 3 * ANIMATION_CYCLE_TIME;
    const TIME_BETWEEN_ANIMATIONS = 1.5 * ANIMATION_CYCLE_TIME;
    
    function animateRandomBox(animationTime) {
      const darkBoxes = document.querySelectorAll(DARK_SELECTOR);
      const numberOfDarkBoxes = darkBoxes.length;
      if (numberOfDarkBoxes === 0) {
        return;
      }
      const randomBoxNumber = Math.floor(Math.random() * numberOfDarkBoxes);
      const randomBoxClass = darkBoxes[randomBoxNumber].classList;
      randomBoxClass.remove('dark');
      randomBoxClass.add('animated');
      setTimeout(() => {
        randomBoxClass.add('dark');
        randomBoxClass.remove('animated');
      }, animationTime);
    }
    
    setInterval(() => animateRandomBox(TOTAL_ANIMATION_TIME), TIME_BETWEEN_ANIMATIONS);
    @keyframes animated_background_color {
      0% {
        background-color: #000;
      }
      25% {
        background-color: #ff9500;
      }
      50% {
        background-color: #ffcb00;
      }
      75% {
        background-color: #ff9500;
      }
      100% {
        background-color: #000;
      }
    }
    
    body {
      display: grid;
      grid-auto-rows: min-content;
      row-gap: 0.25rem;
    }
    
    .box {
      height: 1rem;
      width: 1rem;
      border-radius: 0.5rem;
    }
    
    .dark {
      background-color: black;
    }
    
    .animated {
      animation-name: animated_background_color;
      animation-duration: 2s;
      animation-timing-function: linear;
      animation-iteration-count: infinite;
    }
    <!DOCTYPE html>
    
    <html>
    
    <head>
      <title>Animation</title>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    </head>
    
    <body>
      <div class="box dark"></div>
      <div class="box dark"></div>
      <div class="box dark"></div>
      <div class="box dark"></div>
      <div class="box dark"></div>
    </body>
    
    </html>

    【讨论】:

    • 但是现在动画在元素再次变黑之前只运行一次,我希望它在元素再次变黑之前在动画的第一种颜色和最后一种颜色之间切换多次。
    • 未指定。 1)您可以使用另一个类(例如 .orange)进行过渡:.dark-> .orange -> .animated -> .orange -> .dark,0% 和 100% 设置为橙色 2)您只能使用过渡: .dark -> .orange -> .yellow -> .orange -> .yellow -> ... -> .orange -> .dark 3)您可以在动画中插入更多关键帧来做深色 -> 橙色颜色 -> 黄色 -> 橙色 -> 黄色 -> ... -> 橙色 -> 深色。显然你需要在css和脚本中改变动画时间
    猜你喜欢
    • 1970-01-01
    • 2023-02-10
    • 2019-06-21
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 2016-10-07
    相关资源
    最近更新 更多