Анимация вращающихся чисел при обновлении значения

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

Какой код HTML (+CSS +JS, если необходимо) я могу использовать для этого? Спасибо!

P.S.: Число состоит из двух десятичных знаков и в качестве десятичного разделителя используется ",".

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
0
224
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По иллюстрации на ум пришла вот такая уже не поддерживаемая библиотека:

Пример

const el = document.querySelector('.odometer')
 
const od = new Odometer({
  el: el,
  value: 1234, // default value
 
  // Any option (other than auto and selector) can be passed in here
  format: '( ddd),dd',
  theme: 'default',
})
 
// change to new value
od.update(9876)
// or
el.innerHTML = 9876
<link rel = "stylesheet" href = "http://github.hubspot.com/odometer/themes/odometer-theme-default.css" />
<script src = "http://github.hubspot.com/odometer/odometer.js"></script>

<div class = "odometer"></div>

Пример с вашим дизайном

const values = [4753, 8170]
const el = document.querySelector('.odometer')
const od = new Odometer({
  el: el,
  value: values[0], // default value
 
  // Any option (other than auto and selector) can be passed in here
  format: '( ddd),dd',
  theme: 'default',
})

let index = 1
function infiniteUpdate() {
  od.update(values[index])
  index = (index + 1) % values.length
  setTimeout(infiniteUpdate, 6000)
}
infiniteUpdate()
@import url('https://fonts.googleapis.com/css2?family=Lexend&display=swap');

body {
  background-color: #6c48ff;
}

.circle {
  margin: 0 auto;
  height: 150px;
  width: 150px;
  border-radius: 50%;
  background-color: #242400;
  border: 10px solid #fc6caa;
  
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  
  color: #fff;
  font-size: 37px;
}

/* change font-family */
.circle,
.odometer-value {
  font-family: 'Lexend', sans-serif;
}

/* change default duration from 3s to 5s */
/* https://github.com/HubSpot/odometer/issues/91 */
.odometer.odometer-animating-up .odometer-ribbon-inner, .odometer.odometer-animating-down.odometer-animating .odometer-ribbon-inner {
    -webkit-transition-duration: 5s !important;
    -moz-transition-duration: 5s !important;
    -ms-transition-duration: 5s !important;
    -o-transition-duration: 5s !important;
    transition-duration: 5s !important;
}

/* add shadow */
.odometer::before, .odometer::after {
  content: '';
  position: absolute;
  z-index: 10;
  left: 0;
  width: 100%;
  height: 9px;
}
.odometer::before {
  top: 0;
  background: linear-gradient(to bottom, rgba(36, 36, 0, 1), rgba(36, 36, 0, 0));
}
.odometer::after {
  bottom: 0;
  background: linear-gradient(to top, rgba(36, 36, 0, 1), rgba(36, 36, 0, 0));
}
<link rel = "stylesheet" href = "http://github.hubspot.com/odometer/themes/odometer-theme-default.css" />
<script src = "http://github.hubspot.com/odometer/odometer.js"></script>

<div class = "circle">
  <div>$</div>
  <div class = "odometer"></div>
</div>

Пример с выделенной дробной частью

Быстрая идея для десятичного значения: вы можете вставить два одометра. Первый считает целое число, второй – дробную часть. Таким образом, вы можете обрабатывать их отдельно друг от друга.

const values = [100.2, 109.2]

const elNumber = document.querySelector('.odometer-number')
const odNumber = new Odometer({
  el: elNumber,
  value: parseInt(values[0].toString().split('.')[0]), // default value
 
  // Any option (other than auto and selector) can be passed in here
  format: '( ddd)',
  theme: 'default',
})

const elFract = document.querySelector('.odometer-fractional')
const odFract = new Odometer({
  el: elFract,
  value: parseInt(values[0].toString().split('.')[1]), // default value
 
  // Any option (other than auto and selector) can be passed in here
  format: 'd',
  theme: 'default',
})

let index = 1
function infiniteUpdate() {
  const value = values[index]
  const newNumber = parseInt(value.toString().split('.')[0])
  const newFract = parseInt(value.toString().split('.')[1])
  
  odNumber.update(newNumber)
  odFract.update(newFract)
  
  index = (index + 1) % values.length
  setTimeout(infiniteUpdate, 6000)
}
infiniteUpdate()
@import url('https://fonts.googleapis.com/css2?family=Lexend&display=swap');

body {
  background-color: #6c48ff;
}

.circle {
  margin: 0 auto;
  height: 150px;
  width: 150px;
  border-radius: 50%;
  background-color: #242400;
  border: 10px solid #fc6caa;
  
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  
  color: #fff;
  font-size: 37px;
}

/* change font-family */
.circle,
.odometer-value {
  font-family: 'Lexend', sans-serif;
}

/* change default duration from 3s to 5s */
/* https://github.com/HubSpot/odometer/issues/91 */
.odometer.odometer-animating-up .odometer-ribbon-inner, .odometer.odometer-animating-down.odometer-animating .odometer-ribbon-inner {
    -webkit-transition-duration: 5s !important;
    -moz-transition-duration: 5s !important;
    -ms-transition-duration: 5s !important;
    -o-transition-duration: 5s !important;
    transition-duration: 5s !important;
}

/* add shadow */
.odometer::before, .odometer::after {
  content: '';
  position: absolute;
  z-index: 10;
  left: 0;
  width: 100%;
  height: 9px;
}
.odometer::before {
  top: 0;
  background: linear-gradient(to bottom, rgba(36, 36, 0, 1), rgba(36, 36, 0, 0));
}
.odometer::after {
  bottom: 0;
  background: linear-gradient(to top, rgba(36, 36, 0, 1), rgba(36, 36, 0, 0));
}
<link rel = "stylesheet" href = "http://github.hubspot.com/odometer/themes/odometer-theme-default.css" />
<script src = "http://github.hubspot.com/odometer/odometer.js"></script>

<div class = "circle">
  <div>$</div>
  <div class = "odometer odometer-number"></div>
  <div>,</div>
  <div class = "odometer odometer-fractional"></div>
</div>

Вау, это просто потрясающе @rozszoltan! Очень признателен! Мне просто нужно 2 изменения: 1. Я передаю новое значение каждые X секунд (поэтому нет необходимости устанавливать диапазоны). Как я могу сделать так, чтобы анимировались только затронутые цифры? Т.е. если первое значение равно 10 000,20, а следующее значение — 10 009,20, я просто хочу, чтобы одна цифра анимировалась от «0» до «9». 2. Не могли бы вы обновить свой код, чтобы использовать шрифт Lexend (fonts.googleapis.com/ css?family=Lexend)?

Eu Román 22.04.2024 13:35

При обновлении номера обновляются только необходимые цифры. Я понимаю, что вы имеете в виду, говоря о сохранении неизменяющихся цифр. Быстро просматривая документацию, я не смог найти непосредственного описания этого, но дробная часть обновляется, потому что начинает отсчет вверх: 10000.2, 10000.3, 10000.4 и т. д.

rozsazoltan 22.04.2024 13:40

Я добавил шрифт. Стили CSS будут применяться в зависимости от их специфики. Поскольку у .odometer-value уже было семейство шрифтов, вы можете переопределить его, только напрямую указав семейство шрифтов этого класса. Кроме того, я переопределил .circle из-за знака $.

rozsazoltan 22.04.2024 13:45

Быстрая идея для десятичного значения: вы можете вставить два одометра. Первый считает целое число, второй – дробную часть. Таким образом, вы можете обрабатывать их отдельно друг от друга.

rozsazoltan 22.04.2024 13:54

Я также добавил свою предыдущую идею под названием «Пример с отделенной дробной частью». (Красота ошибки, но просто ради примера я не искал самое идеальное решение для разделения числа с плавающей запятой. Поэтому я составил из него строку и разбил ее по точке.)

rozsazoltan 22.04.2024 14:05

Примечание. Ваш шрифт может не подойти для этой цели, поскольку его символы имеют разную ширину. «Скачок» можно увидеть при переключении с более широкой цифры на более узкую. Возможно, было бы полезно использовать шрифт, в котором каждый символ занимает одинаковое пространство по ширине. Такие шрифты называются «моноширинными».

rozsazoltan 22.04.2024 14:08

Потрясающий @rozsazoltan! Вы полностью решили мой вопрос. Благодаря вашему решению я смог реализовать именно то, что мне было нужно. Большое спасибо!

Eu Román 22.04.2024 17:46

Другие вопросы по теме