PluginProbe
Easy Elements for Elementor – Addons & Website Templates / 1.5.3
Easy Elements for Elementor – Addons & Website Templates v1.5.3
1.5.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.6 1.4.7 1.4.8 1.4.5 1.4.4 1.4.3 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 All 47 releases
easy-elements / widgets / counter / js / counter.js

counter.js in Easy Elements for Elementor – Addons & Website Templates 1.5.3, at widgets/counter/js/counter.js

126 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function ($) {
2 "use strict";
3
4 const SEPARATORS = { comma: ",", dot: ".", space: " ", underline: "_" };
5
6 function formatWithSeparator(num, separator) {
7 const str = num.toString();
8 if (!separator) return str;
9 const negative = str.charAt(0) === "-";
10 const body = negative ? str.slice(1) : str;
11 if (body.length < 4) return str;
12 return (negative ? "-" : "") + body.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
13 }
14
15 function runCounter(counter, target, start, duration, separator) {
16 const startTime = performance.now();
17 function tick(time) {
18 const progress = Math.min((time - startTime) / duration, 1);
19 const current = Math.floor(start + (target - start) * progress);
20 counter.textContent = formatWithSeparator(current, separator);
21 if (progress < 1) requestAnimationFrame(tick);
22 }
23 requestAnimationFrame(tick);
24 }
25
26 function runOdometer(counter, target, duration, separator) {
27 const targetInt = Math.floor(Math.abs(target));
28 const targetStr = targetInt.toString();
29 const negative = target < 0;
30
31 counter.innerHTML = "";
32 counter.classList.add("eel-cnt-odometer-wrap");
33
34 if (negative) {
35 const s = document.createElement("span");
36 s.className = "eel-cnt-odometer-sep";
37 s.textContent = "-";
38 counter.appendChild(s);
39 }
40
41 const animEls = [];
42 let digitIndex = 0;
43
44 for (let i = 0; i < targetStr.length; i++) {
45 const posFromRight = targetStr.length - i;
46 if (i > 0 && separator && posFromRight % 3 === 0) {
47 const sep = document.createElement("span");
48 sep.className = "eel-cnt-odometer-sep";
49 sep.textContent = separator;
50 counter.appendChild(sep);
51 }
52
53 const col = document.createElement("span");
54 col.className = "eel-cnt-odometer-digit";
55
56 const roll = document.createElement("span");
57 roll.className = "eel-cnt-odometer-roll";
58
59 const spins = 2 + digitIndex;
60 let html = "";
61 for (let s = 0; s < spins; s++) {
62 for (let n = 0; n <= 9; n++) {
63 html += '<span class="eel-cnt-odometer-num">' + n + '</span>';
64 }
65 }
66 html += '<span class="eel-cnt-odometer-num">' + targetStr.charAt(i) + '</span>';
67 roll.innerHTML = html;
68 roll.style.transform = "translateY(0)";
69
70 col.appendChild(roll);
71 counter.appendChild(col);
72 animEls.push({ roll: roll, spins: spins });
73 digitIndex++;
74 }
75
76 requestAnimationFrame(function () {
77 requestAnimationFrame(function () {
78 animEls.forEach(function (item) {
79 item.roll.style.transition = "transform " + duration + "ms cubic-bezier(.22,.85,.34,1)";
80 item.roll.style.transform = "translateY(-" + (item.spins * 10) + "em)";
81 });
82 });
83 });
84 }
85
86 function eelRunCounter($scope) {
87 const counters = $scope.find(".eel-counter");
88 if (!counters.length) return;
89
90 const observer = new IntersectionObserver(function (entries) {
91 entries.forEach(function (entry) {
92 if (!entry.isIntersecting) return;
93
94 const counter = entry.target;
95 observer.unobserve(counter);
96
97 const target = parseInt(counter.dataset.count, 10) || 0;
98 const start = parseInt(counter.dataset.start, 10) || 0;
99 const duration = parseInt(counter.dataset.duration, 10) || 1000;
100 const format = counter.dataset.format || "default";
101 const animation = counter.dataset.animation || "counter";
102 const separator = SEPARATORS[format] || "";
103
104 if (animation === "odometer") {
105 runOdometer(counter, target, duration, separator);
106 } else {
107 runCounter(counter, target, start, duration, separator);
108 }
109 });
110 }, { threshold: 0.2 });
111
112 counters.each(function () {
113 observer.observe(this);
114 });
115 }
116
117 $(window).on("elementor/frontend/init", function () {
118 elementorFrontend.hooks.addAction("frontend/element_ready/widget", function ($scope) {
119 if ($scope.find(".eel-counter").length) {
120 eelRunCounter($scope);
121 }
122 });
123 });
124
125 })(jQuery);
126