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.