diff --git a/frontend/about.html b/frontend/about.html index 303a603..1bad327 100644 --- a/frontend/about.html +++ b/frontend/about.html @@ -34,7 +34,7 @@
Click on a tab to visit the site and scroll down for more tabs. Some sites do not allow embedding so clicking them will open a new tab (in your browser) instead.
-Note that, just like the web itself, some sites are broken, profane, fake news, pornographic, trying to harvest your data, serving malware, or an affront to humanity itself. But some of them are pretty cool too.
+Note that, like the web itself, some sites are broken, profane, fake news, pornographic, trying to harvest your data, serving malware, or an affront to humanity itself. But some of them are pretty cool too.
EveryTab just shows a random slice of the web, in all its messy and beautiful glory.
diff --git a/frontend/index.html b/frontend/index.html index 2e42308..9cfe985 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -162,8 +162,24 @@ right: 4px; } - /* Marquee animation driven by Web Animations API in site.js - (pixel-precise endpoints for seamless looping) */ + /* Marquee animations (Chrome/Safari — Firefox uses JS in site.js) */ + .tab-row.scroll-left { + animation: marquee-left var(--speed) linear infinite; + } + + .tab-row.scroll-right { + animation: marquee-right var(--speed) linear infinite; + } + + @keyframes marquee-left { + 0% { transform: translateX(0); } + 100% { transform: translateX(-50%); } + } + + @keyframes marquee-right { + 0% { transform: translateX(-50%); } + 100% { transform: translateX(0); } + } /* Inline iframe viewer */ .iframe-viewer { diff --git a/frontend/site.js b/frontend/site.js index 4cf4d7f..03d785d 100644 --- a/frontend/site.js +++ b/frontend/site.js @@ -118,6 +118,11 @@ function createRow(entries, rowIndex) { // Store config — animation starts after DOM insertion (needs measured width) row._animConfig = { pxPerSec, goLeft, stagger }; + // CSS animation classes for Chrome/Safari (Firefox uses rAF in startRowAnimation) + if (!isFirefox) { + row.classList.add(goLeft ? "scroll-left" : "scroll-right"); + } + // Add tabs twice so the marquee loops seamlessly (translate -50% = one full set) for (let copy = 0; copy < 2; copy++) { for (const entry of entries) { @@ -151,15 +156,10 @@ function startRowAnimation(row) { requestAnimationFrame(tick); } else { - // Chrome/Safari: Web Animations API on the compositor - const duration = halfWidth / pxPerSec * 1000; - const from = goLeft ? "translateX(0px)" : `translateX(-${halfWidth}px)`; - const to = goLeft ? `translateX(-${halfWidth}px)` : "translateX(0px)"; - - row.animate( - [{ transform: from }, { transform: to }], - { duration, iterations: Infinity, easing: "linear", iterationStart: stagger } - ); + // Chrome/Safari: CSS @keyframes animation with calculated duration + const duration = halfWidth / pxPerSec; + row.style.setProperty("--speed", `${duration}s`); + row.style.animationDelay = `${-stagger * duration}s`; } }