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