useFrameSource
Subscribe a callback to a frame source, with automatic cleanup.
Every audiocn-svelte meter and visualizer uses this hook for its source prop. Use it to build your own components on any frame source.
$ pnpm dlx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-frame-source.json$ npx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-frame-source.json$ yarn dlx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-frame-source.json$ bunx --bun shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-frame-source.jsonUsage
<script lang="ts">
import { useFrameSource } from "#lib/hooks/use-frame-source.svelte.js";
import { dbToLevel } from "#lib/audio/decibels.js";
import type { FrameSource, MeterFrame } from "#lib/audio/types.js";
let { source }: { source: FrameSource<MeterFrame> } = $props();
let bar = $state<HTMLDivElement | null>(null);
useFrameSource(
() => source,
(frame) => {
const level = dbToLevel(frame.channels[0]?.peakDb ?? -Infinity);
bar?.style.setProperty("--level", String(level));
}
);
</script>
<div class="h-2 w-40 rounded-full bg-muted">
<div bind:this={bar} class="h-full origin-left scale-x-(--level) rounded-full bg-primary"></div>
</div>The callback runs outside Svelte's reactivity, so it can update the DOM on every frame without touching state. Call the hook during component setup, and pass the source as a getter, () => source, so a new source resubscribes.
API
| Prop | Type | Default |
|---|---|---|
source The source to subscribe to. Changing it resubscribes. | MaybeGetter<FrameSource<T> | null | undefined> | — |
onFrame Called for every frame. It sees current props, so it never causes a resubscribe. | (frame: T) => void | — |
options.enabled Pause the subscription without unmounting. | boolean | true |
options can be an object or a getter, such as () => ({ enabled }).