Я работаю над проектом, в котором я хотел бы иметь возможность точно определить, какие свойства стиля анимация в настоящее время применяет к элементу, и в идеале - только те изменения, которые вносит анимация.
Учитывая приведенный ниже пример, я хотел бы иметь возможность точно знать, как установлены свойства scale
и rotate
, независимо от того, где я приостановил анимацию, без необходимости сортировки присущих свойств, таких как padding
или синий color
, передаваемый другой кнопкой.
Если это просто нелегко выполнимо, ничего страшного, мне просто хотелось бы подтверждения того, что это так. Если да, то я открыт для мозгового штурма разумных альтернатив.
Я видел несколько примеров качества с использованием getComputedStyle()
, и я думаю, что это довольно близко к тому, что я хочу, но в идеале мне нужен объект или строка CSS, которая содержит только свойства стиля, которые применяются анимацией (поэтому нет базовой линии параметры стиля, взятые из файла CSS или примененные другими способами).
Я довольно тщательно просмотрел документацию по API веб-анимации и не нашел ничего, что напрямую отвечало бы моим потребностям. Разумный наивный подход — посмотреть на первый или последний (в зависимости от направления анимации) объект keyFrameEffect в анимации и проверить пары значений свойств на наличие соответствующих свойств, но сколькими способами можно приостановить или завершить анимацию между ними / неожиданные места в цикле анимации, это не похоже на тщательное решение. Например, это не будет работать, если анимация приостановлена или даже находится в состоянии завершения, если установлено такое значение, как iterationStart
, поскольку теперь оно смещает состояние завершения от последнего ключевого кадра.
Возможно, есть способ взять объект анимации и применить его точное текущее состояние к пустому объекту с помощью commitStyles() или чего-то еще, чтобы результирующий объект стилей на пустом элементе содержал только свойства, примененные анимацией? Меня беспокоят пользовательские элементы/свойства, но, возможно, я слишком много об этом думаю.
Независимо от того, что это важно, я не меняю напрямую анимируемый элемент или какие-либо его свойства, поэтому мне нужно быть осторожным и убедиться, что commitStyles влияют только на пустой объект. Возможно, изменив цель ключевых кадров, а затем вернув ее обратно по завершении?
Спасибо заранее за любые предложения!
Пример:
const newspaper = document.querySelector(".newspaper");
const colorChange = document.querySelector(".color-change");
const pauseButton = document.querySelector(".pause");
const finish = document.querySelector(".finish");
// I want a way to directly get the current value of these properties
// without being mixed in with other non animation related css properties
const newspaperSpinning = [
{ transform: "rotate(0) scale(1)" },
{ transform: "rotate(360deg) scale(0.7)" },
];
const newspaperTiming = {
duration: 2000,
iterations: 999,
fill: 'forwards',
iterationStart: 0.3
};
const newspaperKeyFrames = new KeyframeEffect(
newspaper, // element to animate
newspaperSpinning,
newspaperTiming, // keyframe options
);
const animation = new Animation(
newspaperKeyFrames,
document.timeline,
);
newspaper.addEventListener("click", () => {
animation.play()
});
colorChange.addEventListener("click", () => {
newspaper.style.color = 'blue';
});
pauseButton.addEventListener("click", () => {
animation.pause();
});
finish.addEventListener("click", () => {
animation.finish();
});
html,
body {
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: black;
}
button {
cursor: pointer;
}
.newspaper {
padding: 0.5rem;
text-transform: uppercase;
text-align: center;
background-color: white;
cursor: pointer;
}
<div class = "newspaper">click to start spinning newspaper animation</div>
<button class = "color-change">click to change the color</button>
<button class = "pause">click to pause the animation</button>
<button class = "finish">click to finish the animation</button>
Примечание: если на элемент в данный момент действует несколько анимаций, то это нормально и, возможно, даже предпочтительнее, если результатом является список/объект всех свойств стиля, активно передаваемых любой анимацией на элементе.
Да, это, безусловно, хорошая отправная точка, поскольку она позволяет мне выделить последний ключевой кадр среди других деталей, но на самом деле не решает большую часть основной проблемы напрямую. Есть некоторые важные шаги, которые еще предстоит предпринять. Я мог бы опубликовать свое решение, если придумаю хорошее.
редактор спецификации веб-анимации здесь. Если ответить на ваш вопрос просто, то это невозможно. Нам действительно стоит добавить этот API (и он был предложен ранее).
Лучшее, что вы можете сделать на данный момент, это использовать getComputedStyle
. Однако обратите внимание, что getComputedStyle
сериализует значения преобразования как matrix()
(ссылка на спецификацию ), поэтому вы не можете легко проверить отдельные компоненты масштаба и вращения. Один из способов обойти эту проблему — анимировать свойства Scale и Rotate, которые теперь реализованы во всех браузерах, начиная с Baseline 2022.
Подобная проблема актуальна не только для преобразований, но и для всех свойств, поскольку интерполяция анимации происходит в пространстве вычисленных значений. Например, при анимации между 1em
и 20px
вы получите результат в px
.
Чтобы игнорировать влияние других анимаций или стилей на целевой элемент, как вы говорите, вы можете изменить target
KeyframeEffect
на другой элемент, свойства rotate
и scale
которого установлены на initial
или none
(например, используя объявление типа all: initial
) а затем установите его обратно, когда закончите читать getComputedStyle
.
В качестве альтернативы изменению target
, как правило, довольно легко дублировать анимацию и ее эффекты. Вы можете создать клон KeyframeEffect
и новый Animation
и найти Animation
в то же время, что и тот, который вы проверяете, установив для него currentTime
. (В отличие от вызова play()
, который является асинхронным, clone.currentTime = source.currentTime
является синхронным.)
Если вы не знаете, какие свойства анимируются с помощью анимации, вы можете перебрать ключевые кадры и собрать все ключи, которые не являются offset
, composite
или easing
, в Set
.
Обратите внимание, что анимации могут суммироваться и могут добавляться к стилям целевого элемента, поэтому вам нужно подумать, хотите ли вы комбинированный результат (путем указания всех анимаций на зеркальный элемент) или индивидуальный вклад каждой анимации.
Что бы это ни стоило, инструменты разработчика анимации Firefox используют этот подход: создают локальную копию анимации и выбирают ее значения в различных точках, чтобы создать графики эффектов анимации (источник здесь).
Вы изучали getAnimations()?