Запуск анимации CSS в качестве перехода в D3.js

1

У меня есть значение баланса счета, которое я показываю с помощью 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");
}
  • 1
    Я подозреваю, что вам нужна некоторая задержка между удалением классов и их добавлением обратно, или, по крайней мере, операции удаления и добавления классов должны выполняться отдельно. Попробуйте обернуть вторые две -increment и -decrement в setTimeout (хотя может быть более d3-идиоматический способ сделать это).
  • 1
    В качестве альтернативы вы можете использовать задержку для удаления классов -increment и -decrement после завершения анимации перехода. В любом случае, если операция добавления и удаления классов происходит в одном и том же цикле событий, браузер не узнает, что класс действительно изменился, если он установит для класса то же значение, что и раньше.
Теги:
d3.js
animation
transition

1 ответ

0

Вы должны обернуть код, добавляющий новые классы в функцию 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>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню