PageSourceSearch

https://anf.es/wp-content/plugins/header-footer-elementor/inc/js/counter.js?ver=2.9.4

js anf.es collected 2026-09-25 14:58:21 UTC 5,046 bytes, 145 lines download raw bytes

1/**
2 * Counter Widget JavaScript
3 * 
4 * Handles the counter animation functionality
5 */
6
7(function($) {
8    'use strict';
9
10    var HfeCounter = {
11        
12        /**
13         * Initialize the counter
14         */
15        init: function() {
16            elementorFrontend.hooks.addAction('frontend/element_ready/hfe-counter.default', this.initCounter);
17        },
18
19        /**
20         * Initialize counter for specific element
21         */
22        initCounter: function($scope) {
23            var $counter = $scope.find('.hfe-counter-number');
24            
25            if ($counter.length) {
26                HfeCounter.setupCounterAnimation($counter);
27            }
28        },
29
30        /**
31         * Setup counter animation
32         */
33        setupCounterAnimation: function($counter) {
34            var startNumber = parseInt($counter.data('start')) || 0;
35            var endNumber = parseInt($counter.data('end'));
36            endNumber = isNaN(endNumber) ? 100 : endNumber;            
37            var speed = parseInt($counter.data('speed')) || 3000;
38            var separator = $counter.data('separator') || '';
39            
40            // Use Intersection Observer for better performance
41            if ('IntersectionObserver' in window) {
42                var observer = new IntersectionObserver(function(entries) {
43                    entries.forEach(function(entry) {
44                        if (entry.isIntersecting && !$counter.hasClass('hfe-counter-animated')) {
45                            $counter.addClass('hfe-counter-animated');
46                            HfeCounter.animateCounter($counter[0], startNumber, endNumber, speed, separator);
47                            observer.unobserve(entry.target);
48                        }
49                    });
50                }, {
51                    threshold: 0.5
52                });
53                
54                observer.observe($counter[0]);
55            } else {
56                // Fallback for older browsers
57                $(window).on('scroll', function() {
58                    if (HfeCounter.isElementInViewport($counter[0]) && !$counter.hasClass('hfe-counter-animated')) {
59                        $counter.addClass('hfe-counter-animated');
60                        HfeCounter.animateCounter($counter[0], startNumber, endNumber, speed, separator);
61                    }
62                });
63            }
64        },
65
66        /**
67         * Animate the counter
68         */
69        animateCounter: function(element, start, end, duration, separator) {
70            var startTime = null;
71            var $element = $(element);
72            
73            function animate(currentTime) {
74                if (startTime === null) startTime = currentTime;
75                var progress = Math.min((currentTime - startTime) / duration, 1);
76                
77                // Use easing function for smooth animation
78                var easedProgress = HfeCounter.easeOutQuart(progress);
79                var currentNumber = Math.floor(start + (end - start) * easedProgress);
80                
81                $element.text(HfeCounter.formatNumber(currentNumber, separator));
82                
83                if (progress < 1) {
84                    requestAnimationFrame(animate);
85                } else {
86                    $element.text(HfeCounter.formatNumber(end, separator));
87                }
88            }
89            
90            requestAnimationFrame(animate);
91        },
92
93        /**
94         * Format number with separator
95         */
96        formatNumber: function(number, separator) {
97            if (!separator) {
98                return number.toString();
99            }
100            
101            return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
102        },
103
104        /**
105         * Easing function for smooth animation
106         */
107        easeOutQuart: function(t) {
108            return 1 - (--t) * t * t * t;
109        },
110
111        /**
112         * Check if element is in viewport (fallback)
113         */
114        isElementInViewport: function(element) {
115            var rect = element.getBoundingClientRect();
116            return (
117                rect.top >= 0 &&
118                rect.left >= 0 &&
119                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
120                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
121            );
122        }
123    };
124
125    // Initialize when Elementor frontend is ready
126    $(window).on('elementor/frontend/init', function() {
127        HfeCounter.init();
128    });
129
130    // Fallback for when Elementor frontend is not available
131    $(document).ready(function() {
132        if (typeof elementorFrontend === 'undefined') {
133            // Create a mock elementorFrontend for standalone use
134            window.elementorFrontend = {
135                hooks: {
136                    addAction: function(event, callback) {
137                        $(document).ready(callback);
138                    }
139                }
140            };
141        }
142        HfeCounter.init();
143    });
144
145})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.