У меня есть значение баланса счета, которое я показываю с помощью d3. Каждую секунду значение обновляется, и в зависимости от того, увеличивается или уменьшается, я хочу, чтобы он мгновенно мигал зеленым или красным цветом. У меня есть две анимации css, которые обрабатывают флеш-память, и каждый из них управляется классом-модификатором, который может быть добавлен к элементу, например -increase
или -decrease
.
Я использую d3, classed
контролировать эти классы, но где я бегу на некоторые вопросы. Каждый цикл обновления, я проверяю и удаляю оба этих класса, затем условно добавляю соответствующий, чтобы запускать новую анимацию. Проблема в том, что если класс остается таким же, как последний цикл, он не удаляется и не добавляется снова, а затем анимация на триггеры при изменении класса. Как я могу заставить каждую из этих анимаций запускать каждый раз?
function refreshBalance(accounts){
let sum = 0;
for(let i=0; i < accounts.length; i++){
sum = sum + (accounts[i].value * accounts[i].rate);
}
let balance = d3.select(".balance").select(".currency-value");
let diff;
if ((sum - balance.attr("data-balance")) > 0){
diff = "increment";
} else {
diff = "decrement";
}
balance.attr("data-balance", normalizeCurrency(sum, 4, 4))
.text(normalizeCurrency(sum, 4, 4));
balance.classed("-increment", false);
balance.classed("-decrement", false);
balance.classed("-increment", diff === "increment");
balance.classed("-decrement", diff === "decrement");
}
Вы должны обернуть код, добавляющий новые классы в функцию setTimeout
:
balance.classed("-increment", false);
balance.classed("-decrement", false);
setTimeout(function() {
balance.classed("-increment", diff === "increment");
balance.classed("-decrement", diff === "decrement");
});
Маленькая демонстрация:
var divs = d3.select('body')
.data([1,2,3,4,5,6])
.enter()
.append('div')
.text(function(d,i) { return i; })
setInterval(function() {
divs.classed("-increment", false);
divs.classed("-decrement", false);
setTimeout(function() {
divs.classed("-increment", function(d, i) { return i % 2});
divs.classed("-decrement", function(d, i) { return !(i % 2)});
});
}, 3000);
div {
font-size: 30px;
font-weight: bold;
}
.-increment {
animation:increment-animation 1.5s;
}
.-decrement {
animation:decrement-animation 1.5s;
}
@keyframes increment-animation {
0% {
color: black;
}
20% {
color: green;
}
40% {
color: black;
}
60% {
color: green;
}
80% {
color: black;
}
100% {
color: green;
}
}
@keyframes decrement-animation {
0% {
color: black;
}
20% {
color: red;
}
40% {
color: black;
}
60% {
color: red;
}
80% {
color: black;
}
100% {
color: red;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js"></script>
-increment
и-decrement
вsetTimeout
(хотя может быть более d3-идиоматический способ сделать это).-increment
и-decrement
после завершения анимации перехода. В любом случае, если операция добавления и удаления классов происходит в одном и том же цикле событий, браузер не узнает, что класс действительно изменился, если он установит для класса то же значение, что и раньше.