首页 > 解决方案 > CSS颜色是如何动画的

问题描述

我想知道是否有人知道文本颜色(或背景颜色)是如何使用 CSS 过渡设置动画的。假设我们有:

.box {
  background-color: red;
  transition: background-color 2s ease-out;
}

.box:hover {
  background-color: green;
}

因此,在悬停两秒钟的过程中,盒子的颜色会从红色变为绿色,并经过一些褐色。我想知道的是究竟是什么值被操纵以及如何操纵。是rgba吗?十六进制?如果是这样,这些值是如何变化的?从 rgb(255, 0, 0) 到 rgb(123, 122, 0) 到 rgb(0, 255, 0) 线性还是什么?

我的主要目标(除了简单的好奇心)是能够控制颜色变化的进度,说明在时间 A 颜色应该是变化的 30%,而在时间 B 它应该是新颜色的 70% .

很难用谷歌搜索,因为我一直在获取 CSS 动画的教程......

编辑 为了澄清我希望能够根据应用程序状态在某个点/颜色停止动画,而不仅仅是循环播放。做到这一点的唯一方法是如果我知道浏览器实现是如何工作的。

标签: csscss-transitions

解决方案


在过渡或动画期间两种颜色之间的插值与在相同两种颜色之间创建渐变的方式相同。理解它的最简单方法是绘制渐变。

下面是一个例子来说明:

.box {
  background-color: red;
  width:20px;
  height:50px;
  margin-top:-5px;
  animation: change 2s infinite alternate linear;
}


.container {
  height:50px;
  width:400px;
  background:linear-gradient(to right,red,green);
}
@keyframes change {
  to {
    background-color:green;
    transform:translateX(380px);
  }
}
<div class="container">
</div>
<div class="box">

</div>

如果您选择一些颜色,您会发现插值非常简单,并且是在 RGB 空间中完成的。首先,我们使用 rgb 编写我们的两种颜色。在我们的例子中,我们有:

 red = rgb(255,0,0)
 green = rgb(0,128,0)  /* and not rgb(0,255,0) */

然后我们简单地单独插入每种颜色(R、G 和 B)以获得类似的结果:

 rgb(255,0,0)
 rgb(254,2,0)
 rgb(253,4,0)
 rgb(252,6,0)
 ....
 rgb(1,126,0)
 rgb(0,128,0)

下面是一个简单的近似值,但为了更准确,您需要考虑渐变的持续时间或大小。如果我们考虑我们的渐变,我们已经定义400px了宽度,因此400每个像素都有不同的颜色。对于我们要移动的红色2550我们有 256 个值除以 400,因此我们的步长为0.64。对于果岭,我们将有一个步骤0.3225

每个像素的颜色将是从rgb(255 - n*0.64,0 + n*0.3225,0)到的n像素编号。1400

我们对过渡执行相同的逻辑,但我们考虑的是时间而不是宽度。我们有2s,如果我们假设浏览器绘制每个0.01s,我们将需要200值等等..

此外,您应该考虑对每个浏览器可能不同的值的舍入。您还应该知道时间的粒度。我考虑0.01s作为一个例子来说明,但我不知道真正的价值。最重要的是,您应该知道rgb关键字定义的每种颜色的值。跨浏览器的Agreen可能不同。


为了说明上面的计算,这里是一个例子,我将根据两种颜色绘制渐变,它将反映过渡/动画

var sR = (250 - 10) / 400;
var sG = (30 - 80) / 400;
var sB = (150 - 255) / 400;

var canvas = document.querySelector('.container');

var ctx = canvas.getContext('2d');

for (var i = 0; i <= 400; i++) {
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.moveTo(i, 0);
  ctx.lineTo(i, 50);
  ctx.strokeStyle = "rgb(" + (250 - i * sR) + "," + (30 - i * sG) + "," + (150 - i * sB) + ")";
  ctx.stroke();
}
.box {
  background-color: rgb(250, 30, 150);
  width: 20px;
  height: 50px;
  margin-top: -10px;
  animation: change 2s infinite alternate linear;
}

@keyframes change {
  to {
    background-color: rgb(10, 80, 255);
    transform: translateX(380px);
  }
}
<canvas class="container" width="400" height="50"></canvas>
<div class="box">

</div>


推荐阅读