PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.83
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / widgets / Image_Marquee / script.js

script.js in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.83, at includes/widgets/Image_Marquee/script.js

172 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2
3 (function ($) {
4 const initTrack = (track, rootDataset) => {
5 const mergedData = Object.assign({}, rootDataset, track.dataset || {});
6 const orientation = mergedData.orientation || "horizontal";
7 const direction = mergedData.direction || "right_to_left";
8 const pauseHover = mergedData.pauseHover === "yes";
9 const pauseTouch = mergedData.pauseTouch === "yes";
10 const reverseOnHover = mergedData.reverseHover === "yes";
11 const speedRaw = parseFloat(mergedData.speed || "50");
12 const speed = Number.isFinite(speedRaw) ? speedRaw : 50;
13
14 const firstList = track.querySelector(".king-addons-image-marquee__list");
15 if (!firstList) {
16 return null;
17 }
18
19 const baseSign =
20 orientation === "vertical"
21 ? direction === "top_to_bottom"
22 ? 1
23 : -1
24 : direction === "left_to_right"
25 ? 1
26 : -1;
27 let currentSign = baseSign;
28
29 const getBaseSize = () =>
30 orientation === "vertical" ? firstList.scrollHeight : firstList.scrollWidth;
31
32 let baseSize = getBaseSize();
33 if (!baseSize) {
34 return null;
35 }
36
37 let offset = currentSign > 0 ? -baseSize : 0;
38 let paused = false;
39 let rafId = null;
40
41 const applyTransform = () => {
42 if (orientation === "vertical") {
43 track.style.transform = `translate3d(0, ${offset}px, 0)`;
44 } else {
45 track.style.transform = `translate3d(${offset}px, 0, 0)`;
46 }
47 };
48
49 const step = (timestamp) => {
50 const now = timestamp || performance.now();
51 if (!step.last) {
52 step.last = now;
53 }
54 const delta = (now - step.last) / 1000;
55 step.last = now;
56
57 if (!paused) {
58 const pxPerSecond = Math.max(5, speed);
59 offset += currentSign * pxPerSecond * delta;
60
61 if (currentSign < 0 && Math.abs(offset) >= baseSize) {
62 offset += baseSize;
63 } else if (currentSign > 0 && offset >= 0) {
64 offset -= baseSize;
65 }
66
67 applyTransform();
68 }
69
70 rafId = requestAnimationFrame(step);
71 };
72
73 const handleResize = () => {
74 baseSize = getBaseSize();
75 if (baseSize <= 0) {
76 return;
77 }
78 offset = currentSign > 0 ? Math.max(offset, -baseSize) : Math.min(offset, 0);
79 applyTransform();
80 };
81
82 if (pauseHover) {
83 track.addEventListener("mouseenter", () => {
84 paused = true;
85 });
86 track.addEventListener("mouseleave", () => {
87 paused = false;
88 });
89 }
90
91 if (reverseOnHover) {
92 track.addEventListener("mouseenter", () => {
93 currentSign = baseSign * -1;
94 });
95 track.addEventListener("mouseleave", () => {
96 currentSign = baseSign;
97 });
98 }
99
100 if (pauseTouch) {
101 track.addEventListener(
102 "touchstart",
103 () => {
104 paused = true;
105 },
106 { passive: true }
107 );
108 track.addEventListener(
109 "touchend",
110 () => {
111 paused = false;
112 },
113 { passive: true }
114 );
115 }
116
117 applyTransform();
118 rafId = requestAnimationFrame(step);
119
120 const resizeObserver = new ResizeObserver(handleResize);
121 resizeObserver.observe(firstList);
122 resizeObserver.observe(track);
123
124 return () => {
125 if (rafId) {
126 cancelAnimationFrame(rafId);
127 }
128 resizeObserver.disconnect();
129 };
130 };
131
132 const initMarquee = ($scope) => {
133 const root = $scope[0]?.querySelector(".king-addons-image-marquee");
134 if (!root) {
135 return;
136 }
137
138 const tracks = root.querySelectorAll(".king-addons-image-marquee__track");
139 if (!tracks.length) {
140 return;
141 }
142
143 const cleanupFns = [];
144 tracks.forEach((track) => {
145 const cleanup = initTrack(track, root.dataset || {});
146 if (cleanup) {
147 cleanupFns.push(cleanup);
148 }
149 });
150
151 $scope.on("destroy", () => {
152 cleanupFns.forEach((fn) => fn());
153 });
154 };
155
156 $(window).on("elementor/frontend/init", () => {
157 elementorFrontend.hooks.addAction(
158 "frontend/element_ready/king-addons-image-marquee.default",
159 ($scope) => {
160 initMarquee($scope);
161 }
162 );
163 });
164 })(jQuery);
165
166
167
168
169
170
171
172