PageSourceSearch

https://organism.earth/library/scripts/index-topic-ticker.js

js organism.earth collected 2026-10-02 03:27:19 UTC 2,951 bytes, 142 lines download raw bytes

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.