PageSourceSearch

https://shekulli.com.al/js/marquee3k.js

js shekulli.com.al collected 2026-10-02 07:14:28 UTC 5,434 bytes, 202 lines download raw bytes

vendor: 5,434 bytes, lines 1-202
1/**
2 * MARQUEE 3000 MARQUEE 3000 MARQUEE 3000 MARQUEE 3000 MARQUEE 3000
3 * http://github.com/ezekielaquino/marquee3000
4 * Marquees for the new millennium v1.0
5 * MIT License
6 */
7
8;(function(root, factory) {
9  if (typeof define === 'function' && define.amd) {
10    define([], factory);
11  } else if (typeof exports === 'object') {
12    module.exports = factory();
13  } else {
14    root.Marquee3k = factory();
15  }
16}(this, function() {
17  'use strict';
18
19  let animationId = 0;
20
21  class Marquee3k {
22    constructor(element, options) {
23
24      if (element.children.length === 0) {
25        throw new Error("Encountered a marquee element without children, please supply a wrapper for your content");
26      }
27
28      this.element = element;
29      this.selector = options.selector;
30      this.speed = element.dataset.speed || 0.5;
31      this.pausable = element.dataset.pausable;
32      this.reverse = element.dataset.reverse;
33      this.paused = false;
34      this.parent = element.parentElement;
35      this.parentProps = this.parent.getBoundingClientRect();
36      this.content = element.children[0];
37      this.innerContent = this.content.innerHTML;
38      this.wrapStyles = '';
39      this.offset = 0;
40
41      this._setupWrapper();
42      this._setupContent();
43      this._setupEvents();
44
45      this.wrapper.appendChild(this.content);
46      this.element.appendChild(this.wrapper);
47    }
48
49    _setupWrapper() {
50      this.wrapper = document.createElement('div');
51      this.wrapper.classList.add('marquee3k__wrapper');
52      this.wrapper.style.whiteSpace = 'nowrap';
53    }
54
55    _setupContent() {
56      this.content.classList.add(`${this.selector}__copy`);
57      this.content.style.display = 'inline-block';
58      this.contentWidth = this.content.offsetWidth;
59
60      this.requiredReps = this.contentWidth > this.parentProps.width ? 2 : Math.ceil((this.parentProps.width - this.contentWidth) / this.contentWidth) + 1;
61
62      for (let i = 0; i < this.requiredReps; i++) {
63        this._createClone();
64      }
65
66      if (this.reverse) {
67        this.offset = this.contentWidth * -1;
68      }
69
70      this.element.classList.add('is-init');
71    }
72
73    _setupEvents() {
74      this.element.addEventListener('mouseenter', () => {
75        if (this.pausable) this.paused = true;
76      });
77
78      this.element.addEventListener('mouseleave', () => {
79        if (this.pausable) this.paused = false;
80      });
81    }
82
83    _createClone() {
84      const clone = this.content.cloneNode(true);
85      clone.style.display = 'inline-block';
86      clone.classList.add(`${this.selector}__copy`);
87      this.wrapper.appendChild(clone);
88    }
89
90    animate() {
91      if (!this.paused) {
92        const isScrolled = this.reverse ? this.offset < 0 : this.offset > this.contentWidth * -1;
93        const direction = this.reverse ? -1 : 1;
94        const reset = this.reverse ? this.contentWidth * -1 : 0;
95
96        if (isScrolled) this.offset -= this.speed * direction;
97        else this.offset = reset;
98
99        this.wrapper.style.whiteSpace = 'nowrap';
100        this.wrapper.style.transform = `translate(${this.offset}px, 0) translateZ(0)`;
101      }
102    }
103
104    _refresh() {
105      this.contentWidth = this.content.offsetWidth;
106    }
107
108    repopulate(difference, isLarger) {
109      this.contentWidth = this.content.offsetWidth;
110
111      if (isLarger) {
112        const amount = Math.ceil(difference / this.contentWidth) + 1;
113
114        for (let i = 0; i < amount; i++) {
115          this._createClone();
116        }
117      }
118    }
119
120    static refresh(index) {
121      MARQUEES[index]._refresh();
122    }
123
124    static pause(index) {
125      MARQUEES[index].paused = true;
126    }
127
128    static play(index) {
129      MARQUEES[index].paused = false;
130    }
131
132    static toggle(index) {
133      MARQUEES[index].paused = !MARQUEES[index].paused;
134    }
135
136    static refreshAll() {
137      for (let i = 0; i < MARQUEES.length; i++) {
138        MARQUEES[i]._refresh();
139      }
140    }
141
142    static pauseAll() {
143      for (let i = 0; i < MARQUEES.length; i++) {
144        MARQUEES[i].paused = true;
145      }
146    }
147
148    static playAll() {
149      for (let i = 0; i < MARQUEES.length; i++) {
150        MARQUEES[i].paused = false;
151      }
152    }
153
154    static toggleAll() {
155      for (let i = 0; i < MARQUEES.length; i++) {
156        MARQUEES[i].paused = !MARQUEES[i].paused;
157      }
158    }
159
160    static init(options = { selector: 'marquee3k' }) {
161      if (animationId) window.cancelAnimationFrame(animationId);
162
163      window.MARQUEES = [];
164      const marquees = Array.from(document.querySelectorAll(`.${options.selector}`));
165      let previousWidth = window.innerWidth;
166      let timer;
167
168      for (let i = 0; i < marquees.length; i++) {
169        const marquee = marquees[i];
170        const instance = new Marquee3k(marquee, options);
171        MARQUEES.push(instance);
172      }
173
174      animate();
175
176      function animate() {
177        for (let i = 0; i < MARQUEES.length; i++) {
178          MARQUEES[i].animate();
179        }
180        animationId = window.requestAnimationFrame(animate);
181      }
182
183      window.addEventListener('resize', () => {
184        clearTimeout(timer);
185
186        timer = setTimeout(() => {
187          const isLarger = previousWidth < window.innerWidth;
188          const difference = window.innerWidth - previousWidth;
189
190          for (let i = 0; i < MARQUEES.length; i++) {
191            MARQUEES[i].repopulate(difference, isLarger);
192          }
193
194          previousWidth = this.innerWidth;
195        }, 250);
196      });
197    }
198  }
199
200  return Marquee3k;
201
202}));

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.