Viewport Counter Animation
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
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
});
});
run elementor counter when in viewport
### Updated Script:
jQuery(document).ready(function($) {
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
$({ 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)
);
}
});
}
var counters = $('.elementor-counter');
// Hide counters initially
counters.find('.elementor-counter-number').css('opacity', 0);
// 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);
counter.find('.elementor-counter-number').css('opacity', 1); // Make number visible
animateCounter(counter); // Animate the counter
observer.unobserve(entry.target); // Stop observing once animated
}
});
}, { threshold: 0.5 }); // Trigger when 50% of the element is in viewport
// Observe each counter
counters.each(function() {
observer.observe(this);
});
});
### Explanation:
1. **Intersection Observer**:
– Detects when each `.elementor-counter` enters the viewport.
– Triggers the animation only once per counter.
– Stops observing after the animation is triggered, improving performance.
2. **Animation Logic**:
– The `animateCounter` function animates the number counting up to its target value.
3. **Threshold**:
– Set to `0.5` (50%) to start the animation when half the counter is visible.
4. **Improved Performance**:
– Observes elements efficiently without continuously polling or relying on scroll events.
This script will work seamlessly for animating Elementor counters only when they are visible in the viewport.
### Updated Script with `setTimeout`:
jQuery(document).ready(function($) {
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
$({ 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)
);
}
});
}
var counters = $('.elementor-counter');
// Hide counters initially
counters.find('.elementor-counter-number').css('opacity', 0);
// 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);
setTimeout(function() { // Delay before starting the animation
counter.find('.elementor-counter-number').css('opacity', 1); // Make number visible
animateCounter(counter); // Animate the counter
}, 500); // 500ms delay before the animation starts
observer.unobserve(entry.target); // Stop observing once animated
}
});
}, { threshold: 0.5 }); // Trigger when 50% of the element is in viewport
// Observe each counter
counters.each(function() {
observer.observe(this);
});
});
### Changes Made:
1. **`setTimeout` Added**:
– Introduces a 500ms delay (adjustable) before the animation starts when a counter enters the viewport.
2. **Placement**:
– Wrapped the `animateCounter` call inside `setTimeout` to delay the animation execution.
3. **Visibility Adjustment**:
– The counter's number is made visible (`opacity: 1`) before the animation begins after the delay.
### Key Points:
– **Delay Duration**: You can adjust the `500` milliseconds in `setTimeout` to control the delay for each counter.
– **Intersection Observer**: Continues to ensure that the animation is triggered only when the counter is visible in the viewport.
This script provides a smooth and visually appealing delay for the counter animations, enhancing the user experience.