You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.5 KiB
85 lines
2.5 KiB
/** @odoo-module */
|
|
import PublicWidget from "@web/legacy/js/public/public_widget";
|
|
// Extend the PublicWidget.Widget class to create a new widget for the theme
|
|
export const themeIndex = PublicWidget.Widget.extend({
|
|
// Set the selector to the element with id 'wrapwrap', which is the main container of the page
|
|
selector: "#wrapwrap",
|
|
// Define the events to be handled by the widget
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
// The 'start' method is called when the widget is initialized
|
|
|
|
start() {
|
|
this._super(...arguments);
|
|
this.counters = this.$el.find('.number');
|
|
this._setupIntersectionObserver();
|
|
return Promise.resolve();
|
|
},
|
|
|
|
/**
|
|
* Sets up the Intersection Observer to watch counter elements
|
|
* @private
|
|
*/
|
|
_setupIntersectionObserver() {
|
|
const options = {
|
|
root: null, // use viewport
|
|
rootMargin: '0px',
|
|
threshold: 0.5 // trigger when 50% of element is visible
|
|
};
|
|
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting && !entry.target.dataset.animated) {
|
|
this._animateCounter(entry.target);
|
|
}
|
|
});
|
|
}, options);
|
|
|
|
// Observe each counter element
|
|
this.counters.each((_, counter) => {
|
|
observer.observe(counter);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Animates a single counter element
|
|
* @private
|
|
* @param {HTMLElement} counter - The counter element to animate
|
|
*/
|
|
_animateCounter(counter) {
|
|
const speed = 10;
|
|
const $counter = $(counter);
|
|
const target = +$counter.attr("data-target");
|
|
const increment = target / speed;
|
|
|
|
counter.dataset.animated = 'true'; // Mark as animated
|
|
|
|
const updateCounter = (currentValue) => {
|
|
if (currentValue < target) {
|
|
const nextValue = Math.ceil(currentValue + increment);
|
|
counter.innerText = nextValue;
|
|
setTimeout(() => updateCounter(nextValue), 200);
|
|
} else {
|
|
counter.innerText = target;
|
|
}
|
|
};
|
|
|
|
updateCounter(0);// Call the 'updateCounter' function to start the counting animation
|
|
},
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
destroy() {
|
|
this._super(...arguments);
|
|
// Clean up observer if widget is destroyed
|
|
if (this.observer) {
|
|
this.observer.disconnect();
|
|
}
|
|
}
|
|
});
|
|
|
|
// Register the widget
|
|
PublicWidget.registry.themeIndex = themeIndex;
|
|
|