#css #typescript #animation
Вопрос:
У меня есть много отдельных анимаций для разных элементов, которые все делают одно и то же, только с другим цветом. В моем файле .ts у меня есть переменная this.fillColor, которая содержит значение RGB выбранного элемента. Есть ли способ сократить анимацию до 1 блока кода и изменить жестко заданное значение RGB на эту переменную?
#loading {
animation-name: changing;
animation-duration: 4s;
animation-direction: alternate;
animation-iteration-count: infinite;
}
@keyframes changing {
0% {
fill:rgb(105,105,105);
width: 20px;
}
100% {
fill: rgb(250,230,0);
width: 200px;
}
}
#loading2 {
animation-name: changing2;
animation-duration: 4s;
animation-direction: alternate;
animation-iteration-count: infinite;
}
@keyframes changing2 {
0% {
fill:rgb(105,105,105);
width: 20px;
}
100% {
fill: rgb(13,255,191);
width: 200px;
}
}
Ответ №1:
Вы можете просто использовать переменные CSS/пользовательские свойства, чтобы сделать это за вас. Второй аргумент в var()
принимает запасное значение/значение по умолчанию, в случае, если переменная CSS не определена.
Например, если вы хотите задать #loading
начальный и конечный цвета заливки для пользовательского значения, вы можете сделать это:
@keyframes changing {
0% {
fill: var(--loading-fill-from, rgb(105,105,105));
width: 20px;
}
100% {
fill: var(--loading-fill-to, rgb(250,230,0));
width: 200px;
}
}
Это означает, что changing
ключевой кадр будет иметь резервные цвета по умолчанию rgb(105, 105, 105)
для начала и rgb(250, 230, 0)
для конца, но также принимает --loading-fill-from
и --loading-fill-to
пользовательские свойства, если они указаны.
Вы можете установить их в корневом элементе, так как пользовательские свойства CSS наследуются:
document.documentElement.style.setProperty('--loading-fill-from', YOUR_COLOR_HERE);
Ниже приведен пример, подтверждающий концепцию (написан на ES6 JS, но вы можете легко просто преобразовать его в машинописный текст самостоятельно).:
const varNames = ['loading-fill-from', 'loading-fill-to', 'loading2-fill-from', 'loading2-fill-to'];
document.querySelector('#btn').addEventListener('click', () => {
for (let varName of varNames) {
document.documentElement.style.setProperty(`--${varName}`, document.querySelector(`#${varName}`).value);
}
});
#loading {
animation-name: changing;
animation-duration: 4s;
animation-direction: alternate;
animation-iteration-count: infinite;
}
@keyframes changing {
0% {
fill: var(--loading-fill-from, rgb(105,105,105));
width: 20px;
}
100% {
fill: var(--loading-fill-to, rgb(250,230,0));
width: 200px;
}
}
#loading2 {
animation-name: changing2;
animation-duration: 4s;
animation-direction: alternate;
animation-iteration-count: infinite;
}
@keyframes changing2 {
0% {
fill: var(---loading2-fill-from, rgb(105,105,105));
width: 20px;
}
100% {
fill: var(--loading2-fill-to, rgb(13,255,191));
width: 200px;
}
}
<form>
<fieldset>
<legend>#loading</legend>
<label>
Loading button fill from:
<input type="color" id="loading-fill-from" value="#005f73"/>
</label>
<label>
Loading button fill to:
<input type="color" id="loading-fill-to" value="#94d2bd" />
</label>
</fieldset>
<fieldset>
<legend>#loading2</legend>
<label>
Loading2 button fill from:
<input type="color" id="loading2-fill-from" value="#f07167" />
</label>
<label>
Loading2 button fill to:
<input type="color" id="loading2-fill-to" value="#fed9b7" />
</label>
</fieldset>
<button type="button" id="btn">Change color</button>
</form>
<svg id="loading" viewBox="0 0 50 50"><circle cx="25" cy="25" r="20" /></svg>
<svg id="loading2" viewBox="0 0 50 50"><circle cx="25" cy="25" r="20" /></svg>