Как анимируется цвет CSS - PullRequest
       23

Как анимируется цвет CSS

4 голосов
/ 29 октября 2019

Мне интересно, знает ли кто-нибудь, как именно цвет текста (или цвет фона) анимируется с помощью CSS-переходов. Допустим, у нас есть:

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

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

Таким образом, в течение двух секунд зависания коробка меняет цвет с красного на зеленый, проходя через какой-то коричневатый цвет. Что я хочу знать, так это то, какими ценностями точно манипулируют и как. Это RGBA? HEX? Если да, то как меняются эти значения? Переход от rgb (255, 0, 0) к rgb (123, 122, 0) к rgb (0, 255, 0) линейно или что-то еще?

Моя главная цель (кроме простого любопытства) - бытьвозможность контролировать ход изменения цвета, заявив, что в момент времени A цвет должен составлять 30% от изменения, а в момент времени B он должен иметь 70% нового цвета.

Трудно гуглить, поскольку япросто продолжайте получать учебники по CSS-анимации ...

edit Чтобы пояснить, я хочу иметь возможность останавливать анимацию в определенной точке / цвете в зависимости от состояния приложения, а не просто циклически проходить,Единственный способ сделать это, если я знаю, как работают реализации браузера.

Ответы [ 2 ]

1 голос
/ 29 октября 2019

Интерполяция между двумя цветами во время перехода или анимации выполняется аналогично созданию градиента между одними и теми же двумя цветами. Самый простой способ понять это - нарисовать градиент.

Вот пример для иллюстрации:

.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>
0 голосов
/ 29 октября 2019

Редактировать: Реализация браузера зависит от браузера. Поскольку вы пояснили, что ваша главная цель - контролировать ход изменения цвета, я рассмотрел это в следующем ответе с помощью решения.

Помимо этого, вы можете взглянуть на этот CSSсвойство, transition-timing-function.

Далее, цитата из MDN о Использование CSS-переходов :

С включенными CSS-переходами измененияпроисходят в промежутки времени, которые следуют за кривой ускорения, все из которых могут быть настроены.

Анимации, которые включают переход между двумя состояниями, часто называют неявными переходами, так как состояния между начальным и конечным состояниями неявно определяютсябраузер.


Оригинальный ответ:

Это правда, что 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)
    }
}

Я сам вычислил эти значения RGB,основанный на том, что я бы назвал «около 30% и 70%» изменения цвета.

При продолжительности анимации 5 секунд значения 20%, 50% и т. д. означают метку в 1 секунду и2,5 секунды соответственно. Нет способа установить конкретную синхронизацию в CSS (отсюда мое упоминание JS выше).

...