Интерполяция между двумя цветами во время перехода или анимации выполняется аналогично созданию градиента между одними и теми же двумя цветами. Самый простой способ понять это - нарисовать градиент.
Вот пример для иллюстрации:
.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
разных цветов для каждого пикселя. Для красного мы переходим от 255
к 0
, поэтому у нас есть 256 значений, которые мы делим на 400, таким образом, наш шаг будет 0.64
. Для зеленого у нас будет шаг 0.3225
.
. Цвет каждого пикселя будет rgb(255 - n*0.64,0 + n*0.3225,0)
, где n
- номер пикселя от 1
до 400
.
*. 1030 * Мы делаем ту же логику для перехода, но мы рассматриваем время вместо ширины. У нас есть
2s
, и если мы предположим, что браузер рисует каждый
0.01s
, нам понадобятся
200
значения и т. Д.
Кроме того, вы должны рассмотреть округление значений, которые могут небыть одинаковым для каждого браузера. Вы должны также знать гранулярность, когда дело доходит до времен. Я рассмотрел 0.01s
в качестве примера для иллюстрации, но я не знаю реальной стоимости. Самое главное, вы должны знать значение rgb
для каждого цвета, определенного ключевым словом. green
может не совпадать в разных браузерах.
Для иллюстрации приведенного выше расчета приведен пример, в котором я буду рисовать градиент на основе обоих цветов, и он будет отражать переход / анимацию
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>