66 lines
1.5 KiB
Svelte
66 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" />
|