PageSourceSearch

https://www.mirkrasok.ru/local/templates/mirkrasok_2026v2/componen…/brands-index/script.js?17829140649879

js mirkrasok.ru collected 2026-10-03 20:58:54 UTC 9,879 bytes, 334 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function() {
2  const marquee = document.querySelector('.brands-marque');
3
4  if (marquee) {
5    const clone = marquee.innerHTML;
6    marquee.innerHTML = clone + clone;
7  }
8});
9
10var swiper2 = new Swiper(".brands-slider", {
11  observer: true,
12  observeParents: true,
13  observeSlideChildren: true,
14  slidesPerView: "auto",
15  watchSlidesProgress: true,
16  breakpoints: {
17    0: {
18      spaceBetween: 10,
19    },
20    601: {
21      spaceBetween: 20,
22    },
23    1024: {
24      spaceBetween: 20,
25    },
26  },
27  pagination: {
28    el: ".brands-slider .swiper-progressbar",
29    type: "progressbar",
30  },
31});
32
33
34document.addEventListener('DOMContentLoaded', function() {
35    const marque = document.querySelector('.brands-marque');
36    if (!marque) return;
37
38    let position = 0;
39    let isDragging = false;
40    let startX = 0;
41    let startPos = 0;
42    let velocity = 0;
43    let lastX = 0;
44    let lastTime = 0;
45    let animId = null;
46    let isMoving = true;
47    let hasDragged = false; // Флаг перетаскивания
48    
49    const SPEED = 1.0; // Увеличена скорость в 2 раза
50
51    function getContentWidth() {
52        return marque.scrollWidth / 2;
53    }
54
55    function setPosition(x) {
56        position = x;
57        marque.style.transform = 'translateX(' + x + 'px)';
58    }
59
60    function normalize(x) {
61        const w = getContentWidth();
62        if (x > 0) return x - w;
63        if (x < -w) return x + w;
64        return x;
65    }
66
67    function animate() {
68        if (!isMoving || isDragging) {
69            animId = requestAnimationFrame(animate);
70            return;
71        }
72        
73        let newPos = position - SPEED;
74        newPos = normalize(newPos);
75        setPosition(newPos);
76        animId = requestAnimationFrame(animate);
77    }
78
79    function startAnimation() {
80        if (animId) cancelAnimationFrame(animId);
81        isMoving = true;
82        animId = requestAnimationFrame(animate);
83    }
84
85    function stopAnimation() {
86        isMoving = false;
87        if (animId) {
88            cancelAnimationFrame(animId);
89            animId = null;
90        }
91    }
92
93    // ===== TOUCH =====
94    marque.addEventListener('touchstart', function(e) {
95        stopAnimation();
96        isDragging = true;
97        hasDragged = false;
98        const t = e.touches[0];
99        startX = t.clientX;
100        startPos = position;
101        lastX = startX;
102        lastTime = Date.now();
103        velocity = 0;
104    }, { passive: true });
105
106    marque.addEventListener('touchmove', function(e) {
107        if (!isDragging) return;
108        e.preventDefault();
109        
110        hasDragged = true; // Отмечаем, что было перетаскивание
111        
112        const t = e.touches[0];
113        const now = Date.now();
114        const dx = t.clientX - lastX;
115        const dt = now - lastTime;
116        
117        if (dt > 0) velocity = (dx / dt) * 10;
118        
119        lastX = t.clientX;
120        lastTime = now;
121        
122        let newPos = startPos + (t.clientX - startX);
123        const w = getContentWidth();
124        const containerWidth = marque.parentElement.offsetWidth;
125        const min = -w + containerWidth;
126        const max = 0;
127        
128        if (newPos > max) newPos = max + (newPos - max) * 0.2;
129        if (newPos < min) newPos = min + (newPos - min) * 0.2;
130        
131        setPosition(newPos);
132    }, { passive: false });
133
134    marque.addEventListener('touchend', function(e) {
135        if (!isDragging) return;
136        isDragging = false;
137        
138        const w = getContentWidth();
139        const containerWidth = marque.parentElement.offsetWidth;
140        const min = -w + containerWidth;
141        const max = 0;
142        
143        // Если было перетаскивание - отменяем клик
144        if (hasDragged) {
145            e.preventDefault();
146            // Сбрасываем флаг через 300ms после окончания касания
147            setTimeout(() => {
148                hasDragged = false;
149            }, 300);
150        }
151        
152        // Инерция
153        if (Math.abs(velocity) > 0.3) {
154            let v = velocity;
155            const friction = 0.97;
156            
157            function decelerate() {
158                v *= friction;
159                let newPos = position + v;
160                
161                if (newPos > max) {
162                    newPos = max + (newPos - max) * 0.1;
163                    v *= 0.8;
164                }
165                if (newPos < min) {
166                    newPos = min + (newPos - min) * 0.1;
167                    v *= 0.8;
168                }
169                
170                newPos = normalize(newPos);
171                setPosition(newPos);
172                
173                if (Math.abs(v) > 0.1) {
174                    requestAnimationFrame(decelerate);
175                } else {
176                    setPosition(normalize(position));
177                    startAnimation();
178                }
179            }
180            decelerate();
181        } else {
182            setPosition(normalize(position));
183            startAnimation();
184        }
185    }, { passive: false });
186
187    marque.addEventListener('touchcancel', function() {
188        if (isDragging) {
189            isDragging = false;
190            hasDragged = false;
191            setPosition(normalize(position));
192            startAnimation();
193        }
194    }, { passive: true });
195
196    // ===== MOUSE =====
197    marque.addEventListener('mousedown', function(e) {
198        stopAnimation();
199        isDragging = true;
200        hasDragged = false;
201        startX = e.clientX;
202        startPos = position;
203        lastX = startX;
204        lastTime = Date.now();
205        velocity = 0;
206        e.preventDefault();
207    }, { passive: false });
208
209    document.addEventListener('mousemove', function(e) {
210        if (!isDragging) return;
211        
212        hasDragged = true; // Отмечаем, что было перетаскивание
213        
214        const now = Date.now();
215        const dx = e.clientX - lastX;
216        const dt = now - lastTime;
217        
218        if (dt > 0) velocity = (dx / dt) * 10;
219        
220        lastX = e.clientX;
221        lastTime = now;
222        
223        let newPos = startPos + (e.clientX - startX);
224        const w = getContentWidth();
225        const containerWidth = marque.parentElement.offsetWidth;
226        const min = -w + containerWidth;
227        const max = 0;
228        
229        if (newPos > max) newPos = max + (newPos - max) * 0.2;
230        if (newPos < min) newPos = min + (newPos - min) * 0.2;
231        
232        setPosition(newPos);
233    }, { passive: false });
234
235    document.addEventListener('mouseup', function(e) {
236        if (!isDragging) return;
237        isDragging = false;
238        
239        const w = getContentWidth();
240        const containerWidth = marque.parentElement.offsetWidth;
241        const min = -w + containerWidth;
242        const max = 0;
243        
244        // Если было перетаскивание - отменяем клик
245        if (hasDragged) {
246            e.preventDefault();
247            // Сбрасываем флаг через 300ms
248            setTimeout(() => {
249                hasDragged = false;
250            }, 300);
251        }
252        
253        if (Math.abs(velocity) > 0.3) {
254            let v = velocity;
255            const friction = 0.97;
256            
257            function decelerate() {
258                v *= friction;
259                let newPos = position + v;
260                
261                if (newPos > max) {
262                    newPos = max + (newPos - max) * 0.1;
263                    v *= 0.8;
264                }
265                if (newPos < min) {
266                    newPos = min + (newPos - min) * 0.1;
267                    v *= 0.8;
268                }
269                
270                newPos = normalize(newPos);
271                setPosition(newPos);
272                
273                if (Math.abs(v) > 0.1) {
274                    requestAnimationFrame(decelerate);
275                } else {
276                    setPosition(normalize(position));
277                    startAnimation();
278                }
279            }
280            decelerate();
281        } else {
282            setPosition(normalize(position));
283            startAnimation();
284        }
285    }, { passive: false });
286
287    // Остановка при наведении (только для десктопа)
288    let isHovering = false;
289    
290    marque.addEventListener('mouseenter', function() {
291        isHovering = true;
292        if (!isDragging) {
293            stopAnimation();
294        }
295    });
296
297    marque.addEventListener('mouseleave', function() {
298        isHovering = false;
299        // Возобновляем анимацию, если не перетаскиваем и не наведены
300        if (!isDragging && !isMoving) {
301            startAnimation();
302        }
303    });
304
305    // ===== ОБРАБОТЧИК КЛИКОВ ПО ССЫЛКАМ =====
306    const links = marque.querySelectorAll('.brands-group');
307    links.forEach(link => {
308        link.addEventListener('click', function(e) {
309            // Если было перетаскивание - отменяем клик
310            if (hasDragged) {
311                e.preventDefault();
312                e.stopPropagation();
313                return false;
314            }
315            // Иначе разрешаем переход по ссылке
316            return true;
317        });
318    });
319
320    // ===== ОБРАБОТКА РЕСАЙЗА =====
321    let resizeTimeout;
322    window.addEventListener('resize', function() {
323        clearTimeout(resizeTimeout);
324        resizeTimeout = setTimeout(function() {
325            let newPos = normalize(position);
326            setPosition(newPos);
327        }, 200);
328    });
329
330    // ===== ЗАПУСК =====
331    startAnimation();
332
333    console.log('✅ Бесконечная прокрутка с инерцией запущена');
334});

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.