На сайте у меня есть счетчик чисел, который всегда увеличивается, без какой-либо замысловатой анимации. Теперь мне нужно анимировать его каждый раз, когда число обновляется, вот так:
Какой код HTML (+CSS +JS, если необходимо) я могу использовать для этого? Спасибо!
P.S.: Число состоит из двух десятичных знаков и в качестве десятичного разделителя используется ",".
По иллюстрации на ум пришла вот такая уже не поддерживаемая библиотека:
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>
При обновлении номера обновляются только необходимые цифры. Я понимаю, что вы имеете в виду, говоря о сохранении неизменяющихся цифр. Быстро просматривая документацию, я не смог найти непосредственного описания этого, но дробная часть обновляется, потому что начинает отсчет вверх: 10000.2, 10000.3, 10000.4 и т. д.
Я добавил шрифт. Стили CSS будут применяться в зависимости от их специфики. Поскольку у .odometer-value
уже было семейство шрифтов, вы можете переопределить его, только напрямую указав семейство шрифтов этого класса. Кроме того, я переопределил .circle
из-за знака $.
Быстрая идея для десятичного значения: вы можете вставить два одометра. Первый считает целое число, второй – дробную часть. Таким образом, вы можете обрабатывать их отдельно друг от друга.
Я также добавил свою предыдущую идею под названием «Пример с отделенной дробной частью». (Красота ошибки, но просто ради примера я не искал самое идеальное решение для разделения числа с плавающей запятой. Поэтому я составил из него строку и разбил ее по точке.)
Примечание. Ваш шрифт может не подойти для этой цели, поскольку его символы имеют разную ширину. «Скачок» можно увидеть при переключении с более широкой цифры на более узкую. Возможно, было бы полезно использовать шрифт, в котором каждый символ занимает одинаковое пространство по ширине. Такие шрифты называются «моноширинными».
Потрясающий @rozsazoltan! Вы полностью решили мой вопрос. Благодаря вашему решению я смог реализовать именно то, что мне было нужно. Большое спасибо!
Вау, это просто потрясающе @rozszoltan! Очень признателен! Мне просто нужно 2 изменения: 1. Я передаю новое значение каждые X секунд (поэтому нет необходимости устанавливать диапазоны). Как я могу сделать так, чтобы анимировались только затронутые цифры? Т.е. если первое значение равно 10 000,20, а следующее значение — 10 009,20, я просто хочу, чтобы одна цифра анимировалась от «0» до «9». 2. Не могли бы вы обновить свой код, чтобы использовать шрифт Lexend (fonts.googleapis.com/ css?family=Lexend)?