Decimal Counter Animation Fix
January 15, 2025 ยท AI Conversations
$('.elementor-counter-number').css('opacity', 0); // Hide numbers initially
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = parseFloat(counter.find('.elementor-counter-number').data('to-value')); // Get the target value as a float
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Start counting with a delay
setTimeout(function() {
counter.find('.elementor-counter-number').css('opacity', 1); // Make the number visible
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
// Display the number with decimals
counter.find('.elementor-counter-number').text(this.countNum.toFixed(2));
},
complete: function() {
// Ensure it shows the final value with decimals
counter.find('.elementor-counter-number').text(this.countNum.toFixed(2));
}
});
}, index * 1500); // Delay between each counter
});
});
apply decimal to decimal counter only
Here's the updated code:
jQuery(document).ready(function($) {
$('.elementor-counter-number').css('opacity', 0); // Hide numbers initially
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = parseFloat(counter.find('.elementor-counter-number').data('to-value')); // Get the target value as a float
var hasDecimals = countTo % 1 !== 0; // Check if the number has decimals
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Start counting with a delay
setTimeout(function() {
counter.find('.elementor-counter-number').css('opacity', 1); // Make the number visible
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
// Display the number with or without decimals
counter.find('.elementor-counter-number').text(
hasDecimals ? this.countNum.toFixed(2) : Math.floor(this.countNum)
);
},
complete: function() {
// Ensure it shows the final value with or without decimals
counter.find('.elementor-counter-number').text(
hasDecimals ? this.countNum.toFixed(2) : Math.floor(this.countNum)
);
}
});
}, index * 1500); // Delay between each counter
});
});
### Key Changes:
1. **Check for Decimals**:
– Added a `hasDecimals` variable to determine if `countTo` contains decimal points.
2. **Formatting Based on `hasDecimals`**:
– Used `.toFixed(2)` for numbers with decimals.
– Used `Math.floor()` for integers to avoid decimal display.
This way, only decimal counters will show decimal values during the animation, while integer counters will display whole numbers.
### Updated Code:
jQuery(document).ready(function($) {
$('.elementor-counter-number').css('opacity', 0); // Hide numbers initially
// Function to animate the counter
function animateCounter(counter) {
var countTo = parseFloat(counter.find('.elementor-counter-number').data('to-value')); // Get the target value as a float
var hasDecimals = countTo % 1 !== 0; // Check if the number has decimals
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
counter.find('.elementor-counter-number').css('opacity', 1); // Make the number visible
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
// Display the number with or without decimals
counter.find('.elementor-counter-number').text(
hasDecimals ? this.countNum.toFixed(2) : Math.floor(this.countNum)
);
},
complete: function() {
// Ensure it shows the final value with or without decimals
counter.find('.elementor-counter-number').text(
hasDecimals ? this.countNum.toFixed(2) : Math.floor(this.countNum)
);
}
});
}
// Use Intersection Observer to trigger animation when in viewport
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var counter = $(entry.target);
if (!counter.hasClass('animated')) { // Avoid re-animation
counter.addClass('animated');
animateCounter(counter);
}
}
});
}, {
threshold: 0.5 // Trigger when 50% of the element is visible
});
// Observe each counter
$('.elementor-counter').each(function() {
observer.observe(this);
});
});
### Explanation:
1. **Intersection Observer**:
– Monitors when `.elementor-counter` elements enter or exit the viewport.
2. **Avoid Re-animation**:
– Added a check with the `animated` class to ensure each counter animates only once.
3. **Animation Trigger**:
– Animates the counter only when at least 50% of it is visible (`threshold: 0.5`).
4. **Performance**:
– Using `IntersectionObserver` is more efficient than continuously checking with scroll events.
This ensures the counters animate only when they are visible in the viewport, enhancing performance and user experience.