line-and-surface/src/components/AudioArea.svelte

67 lines
1.5 KiB
Svelte

<script lang="ts" context="module">
export interface AudioAreaDef {
id: string;
cx: number;
cy: number;
radius: number;
src: string;
}
</script>
<script lang="ts">
import type { BoundingBox } from "./SVGContent.svelte";
export let definition: AudioAreaDef;
export let bbox: BoundingBox;
let audio: HTMLAudioElement;
console.debug(`[AUDIOAREA] Initializing ${definition.src}...`);
// console.debug({definition});
const MIN_SCALE = 0.02;
const MIN_VOLUME_MULTIPLIER = 0.33;
const vol_x = (1 - MIN_VOLUME_MULTIPLIER) / (1 - MIN_SCALE);
const vol_b = 1 - vol_x;
function onBBoxChange() {
if (!audio) {
return;
}
const x = bbox.x + bbox.w / 2;
const y = bbox.y + bbox.h / 2;
const distance = Math.sqrt(
Math.pow(x - definition.cx, 2) + Math.pow(y - definition.cy, 2)
);
if (distance < definition.radius) {
if (audio.paused) {
console.debug(
`[AUDIOAREA] Entered audio area "${definition.src}", starting playback...`
);
audio.play();
}
const volume = (definition.radius - distance) / definition.radius;
audio.volume = volume * (bbox.z < 1 ? bbox.z * vol_x + vol_b : 1);
} else {
if (!audio.paused) {
console.debug(
`[AUDIOAREA] Left audio area "${definition.src}", pausing playback...`
);
audio.pause();
}
}
}
$: {
bbox.x;
bbox.y;
bbox.w;
bbox.h;
bbox.z;
onBBoxChange();
}
</script>
<audio bind:this={audio} src={definition.src} loop preload="auto" />