1const ticker = document.getElementById('explore-topics'); 2const list = document.getElementById('topic-list'); 3 4const cardSize = getCardSize(); 5let windowWidth = window.innerWidth; 6let visibleCards = null; 7let triggerL, triggerR; 8updateTriggers(); 9 10let edgeLeft = false; 11let edgeRight = false; 12let tickerHover = false; 13 14let vFast = 2.5; 15let vNormal = 0.5; 16 17let tickerOffset = -cardSize / 2; 18let tickerSpeed = vNormal; 19let targetSpeed = vNormal; 20 21let firstCard, lastCard; 22updateEdgeCards(); 23 24for (let card of list.children) { 25 card.classList.remove('no-bg-image'); 26} 27 28requestAnimationFrame(scroll); 29function scroll() { 30 31 shiftCards(); 32 updateTickerSpeed(); 33 34 tickerOffset -= tickerSpeed; 35 list.style.transform = `translate3d(${tickerOffset}px, 0, 0)`; 36 37 requestAnimationFrame(scroll); 38} 39 40function shiftCards() { 41 42 if ( 43 edgeLeft === false && 44 tickerOffset < -1 * cardSize 45 ) { 46 list.append(firstCard); 47 updateEdgeCards(); 48 49 tickerOffset += (cardSize + 2); 50 51 } else if ( 52 edgeLeft === true && 53 tickerOffset >= 0 54 ) { 55 list.prepend(lastCard); 56 updateEdgeCards(); 57 58 tickerOffset -= (cardSize + 2); 59 } 60 61} 62 63function updateEdgeCards() { 64 firstCard = list.children[0]; 65 lastCard = list.children[list.children.length - 1]; 66 updateVisibility(); 67} 68 69function updateTickerSpeed() { 70 if (tickerHover === true) { 71 72 if (edgeRight === true) { 73 targetSpeed = vFast; 74 } else if (edgeLeft === true) { 75 targetSpeed = -1 * vFast; 76 } else { 77 targetSpeed = 0.0; 78 } 79 80 } else { 81 targetSpeed = vNormal; 82 } 83 84 if (tickerSpeed !== targetSpeed) { 85 if (Math.round(tickerSpeed * 100) / 100 === targetSpeed) { 86 tickerSpeed = targetSpeed; 87 } else { 88 tickerSpeed = lerp(tickerSpeed, targetSpeed, 0.045); 89 } 90 } 91} 92 93function updateVisibility() { 94 const children = list.children; 95 for (let i = 0, len = children.length; i < len; i++) { 96 if (i < visibleCards) { 97 children[i].classList.remove('invisible'); 98 } else { 99 children[i].classList.add('invisible'); 100 } 101 } 102} 103 104ticker.addEventListener('pointerenter', (event) => { 105 tickerHover = true; 106}); 107 108ticker.addEventListener('pointermove', (event) => { 109 edgeLeft = (event.clientX <= triggerL) ? true : false; 110 edgeRight = (event.clientX >= triggerR) ? true : false; 111}); 112 113ticker.addEventListener('pointerleave', (event) => { 114 tickerHover = false; 115 edgeLeft = false; 116 edgeRight = false; 117}); 118 119window.addEventListener('resize', () => { 120 windowWidth = window.innerWidth; 121 updateTriggers(); 122}); 123 124 125function getCardSize() { 126 const e = document.getElementsByClassName('topic-card')[0]; 127 const style = window.getComputedStyle(e); 128 const width = style.width.replace('px', ''); 129 const margin = style.marginLeft.replace('px', ''); 130 131 return parseFloat(width) + parseFloat(margin) + parseFloat(margin); 132} 133 134function updateTriggers() { 135 triggerL = cardSize / 3; 136 triggerR = windowWidth - triggerL; 137 visibleCards = Math.ceil(windowWidth / cardSize) + 1; 138} 139 140function lerp(start, stop, amt) { 141 return amt * (stop - start) + start; 142}
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.