CSS 颜色如何动画
How is CSS color animated
我想知道是否有人知道文本颜色(或背景颜色)是如何使用 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新颜色的百分比。
很难 google 因为我一直在获取 CSS 动画教程...
编辑
澄清一下,我希望能够根据应用程序状态在某个 point/color 处停止动画,而不仅仅是循环播放。如果我知道浏览器实现的工作原理,唯一的方法就是这样做。
编辑:
浏览器实现因浏览器而异。由于您阐明了您的主要目标是能够控制颜色变化的进度,因此我在下面的这个答案中通过解决方案解决了这个问题。
除此之外,您可能还想看看这个 CSS 属性、transition-timing-function
.
此外,Using CSS transitions 上来自 MDN 的引用:
With CSS transitions enabled, changes occur at time intervals that follow an acceleration curve, all of which can be customized.
Animations that involve transitioning between two states are often called implicit transitions as the states in between the start and final states are implicitly defined by the browser.
原回答:
的确,CSS 动画是一种实现方式。除此之外,您可以使用 javascript 进行这种微调控制。
例如,您可以设置这样的动画:
@keyframes specialFade {
0% {
background-color: rgb(255, 0, 0);
}
20% {
background-color: rgb(175, 80, 0)
}
50% {
background-color: rgb(80, 175, 0)
}
100% {
background-color: rgb(0, 255, 0)
}
}
我根据颜色变化 "about 30% and 70%" 自己计算了这些 rgb 值。
在5秒的动画时长中,20%、50%等分别指的是1秒标记和2.5秒标记。无法在 CSS 中设置特定时间(因此我在上面提到了 JS)。
过渡或动画期间两种颜色之间的插值与在相同两种颜色之间创建渐变的方式相同。最简单的理解方式就是画渐变。
这里举例说明:
.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 space 中完成的。首先,我们使用 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
不同的颜色。对于红色,我们从 255
移动到 0
,所以我们有 256 个值除以 400,因此我们的步骤将是 0.64
。对于绿色,我们将有一个步骤 0.3225
.
每个像素的颜色将为 rgb(255 - n*0.64,0 + n*0.3225,0)
,其中 n
是从 1
到 400
的像素编号。
我们对过渡执行相同的逻辑,但我们考虑的是时间而不是宽度。我们有 2s
,如果我们假设浏览器绘制每个 0.01s
,我们将需要 200
个值,依此类推..
此外,您应该考虑四舍五入的值,每个浏览器的值可能不一样。您还应该了解时间的粒度。我考虑 0.01s
作为例子来说明,但我不知道真正的价值。最重要的是,您应该知道关键字定义的每种颜色的 rgb
值。 green
在浏览器中可能不一样。
为了说明上面的计算,这里有一个例子,我将根据两种颜色绘制渐变,它将反映 transition/animation
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>
我想知道是否有人知道文本颜色(或背景颜色)是如何使用 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新颜色的百分比。
很难 google 因为我一直在获取 CSS 动画教程...
编辑 澄清一下,我希望能够根据应用程序状态在某个 point/color 处停止动画,而不仅仅是循环播放。如果我知道浏览器实现的工作原理,唯一的方法就是这样做。
编辑: 浏览器实现因浏览器而异。由于您阐明了您的主要目标是能够控制颜色变化的进度,因此我在下面的这个答案中通过解决方案解决了这个问题。
除此之外,您可能还想看看这个 CSS 属性、transition-timing-function
.
此外,Using CSS transitions 上来自 MDN 的引用:
With CSS transitions enabled, changes occur at time intervals that follow an acceleration curve, all of which can be customized.
Animations that involve transitioning between two states are often called implicit transitions as the states in between the start and final states are implicitly defined by the browser.
原回答:
的确,CSS 动画是一种实现方式。除此之外,您可以使用 javascript 进行这种微调控制。
例如,您可以设置这样的动画:
@keyframes specialFade {
0% {
background-color: rgb(255, 0, 0);
}
20% {
background-color: rgb(175, 80, 0)
}
50% {
background-color: rgb(80, 175, 0)
}
100% {
background-color: rgb(0, 255, 0)
}
}
我根据颜色变化 "about 30% and 70%" 自己计算了这些 rgb 值。
在5秒的动画时长中,20%、50%等分别指的是1秒标记和2.5秒标记。无法在 CSS 中设置特定时间(因此我在上面提到了 JS)。
过渡或动画期间两种颜色之间的插值与在相同两种颜色之间创建渐变的方式相同。最简单的理解方式就是画渐变。
这里举例说明:
.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 space 中完成的。首先,我们使用 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
不同的颜色。对于红色,我们从 255
移动到 0
,所以我们有 256 个值除以 400,因此我们的步骤将是 0.64
。对于绿色,我们将有一个步骤 0.3225
.
每个像素的颜色将为 rgb(255 - n*0.64,0 + n*0.3225,0)
,其中 n
是从 1
到 400
的像素编号。
我们对过渡执行相同的逻辑,但我们考虑的是时间而不是宽度。我们有 2s
,如果我们假设浏览器绘制每个 0.01s
,我们将需要 200
个值,依此类推..
此外,您应该考虑四舍五入的值,每个浏览器的值可能不一样。您还应该了解时间的粒度。我考虑 0.01s
作为例子来说明,但我不知道真正的价值。最重要的是,您应该知道关键字定义的每种颜色的 rgb
值。 green
在浏览器中可能不一样。
为了说明上面的计算,这里有一个例子,我将根据两种颜色绘制渐变,它将反映 transition/animation
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>