Created
October 12, 2025 13:09
-
-
Save harryqt/fe4f59a9e720b8dbc1767e715838fe49 to your computer and use it in GitHub Desktop.
Svelte 5 + Runed Scroll-Aware Moving Ad Block
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
import { onMount } from 'svelte'; | |
import { useIntersectionObserver, ScrollState } from 'runed'; | |
import { randomInt } from 'es-toolkit'; | |
let boxes = Array.from({ length: 40 }); | |
let adIndex = $state(8); | |
let scroll; | |
let wasIntersecting; | |
let target = $state(null); | |
let isIntersecting = $state(false); | |
onMount(() => { | |
scroll = new ScrollState({ | |
element: window | |
}); | |
}); | |
useIntersectionObserver( | |
() => target, | |
(entries) => { | |
const entry = entries[0]; | |
if (!entry || !scroll) return; | |
isIntersecting = entry.isIntersecting; | |
if (wasIntersecting && !entry.isIntersecting) { | |
if (scroll.directions.bottom) { | |
adIndex = (adIndex + randomInt(10, 12)) % boxes.length; | |
} else if (scroll.directions.top) { | |
let newIndex = (adIndex - randomInt(10, 12)) % boxes.length; | |
adIndex = newIndex < 0 ? (adIndex = 3) : (adIndex = newIndex); | |
} | |
isIntersecting = false; | |
wasIntersecting = false; | |
} | |
wasIntersecting = entry.isIntersecting; | |
} | |
); | |
</script> | |
<header class="sticky top-0 bg-white py-2 text-center shadow"> | |
{#if isIntersecting} | |
Ad in view (index {adIndex}) | |
{:else} | |
Moved → index {adIndex} | |
{/if} | |
</header> | |
<main class="flex flex-wrap items-center justify-center gap-6"> | |
{#each boxes as _, i} | |
<article class="h-64 w-96 bg-amber-100"></article> | |
{#if i === adIndex} | |
<div bind:this={target} class="h-56 w-[728px] bg-blue-200 transition-all duration-300"> | |
Ad block at index {adIndex} | |
</div> | |
{/if} | |
{/each} | |
</main> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment