actual volume animation (in App)
This commit is contained in:
parent
fd11ab1ca1
commit
382f2e34d4
2 changed files with 29 additions and 20 deletions
29
src/App.vue
29
src/App.vue
|
@ -2,7 +2,7 @@
|
|||
<div id="app">
|
||||
<div class="channels">
|
||||
<template v-for="i in N_CHANNELS">
|
||||
<Channel :url="defaultMedia[i-1]" :key="i" class="channel" ref="channels"/>
|
||||
<Channel :url="defaultMedia[i-1]" :volume="volumes[i-1]" :key="i" class="channel" ref="channels"/>
|
||||
</template>
|
||||
</div>
|
||||
<button @click="start">START</button>
|
||||
|
@ -21,16 +21,41 @@ import Channel from "@/components/Channel.vue";
|
|||
})
|
||||
export default class App extends Vue {
|
||||
private readonly N_CHANNELS = 6;
|
||||
private readonly LFO_PERIOD = 30_000;
|
||||
private readonly LFO_DEPTH = 33;
|
||||
private readonly LFO_OFFSET = 66;
|
||||
|
||||
private volumes = Array(this.N_CHANNELS).fill(50);
|
||||
private animateVolumeStart?: Date;
|
||||
private animateVolumeInterval?: number;
|
||||
|
||||
private defaultMedia = [
|
||||
"https://www.youtube.com/watch?v=q76bMs-NwRk"
|
||||
"https://www.youtube.com/watch?v=q76bMs-NwRk",
|
||||
];
|
||||
|
||||
private start() {
|
||||
(this.$refs.channels as Channel[]).forEach((channel) => {
|
||||
channel.start();
|
||||
this.animateVolume();
|
||||
});
|
||||
}
|
||||
|
||||
private animateVolume() {
|
||||
clearInterval(this.animateVolumeInterval);
|
||||
this.animateVolumeStart = new Date();
|
||||
this.animateVolumeInterval = setInterval(() => {
|
||||
if (this.animateVolumeStart) {
|
||||
const delta = new Date().getTime() - this.animateVolumeStart.getTime();
|
||||
|
||||
this.volumes = [...Array(this.N_CHANNELS).keys()]
|
||||
.map((idx) => {
|
||||
const offset = idx * (1 / this.N_CHANNELS);
|
||||
const progress = delta / this.LFO_PERIOD + offset;
|
||||
return Math.sin(progress * 2 * Math.PI) * this.LFO_DEPTH + this.LFO_OFFSET;
|
||||
});
|
||||
}
|
||||
}, 1000 / 60);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -32,14 +32,11 @@ enum ChannelState {
|
|||
|
||||
@Component
|
||||
export default class Channel extends Vue {
|
||||
@Prop() private url: string | undefined;
|
||||
@Prop() public volume: number = 50;
|
||||
@Prop() public url: string | undefined;
|
||||
private youtubePlayer?: YouTubePlayer;
|
||||
private animateVolumeStart?: Date;
|
||||
private animateVolumeInterval?: number;
|
||||
private state = ChannelState.UNLOADED;
|
||||
private title = "";
|
||||
private volume: number = 50;
|
||||
|
||||
|
||||
private get source() {
|
||||
if (this.url) {
|
||||
|
@ -63,7 +60,6 @@ export default class Channel extends Vue {
|
|||
this.youtubePlayer.setVolume(this.volume);
|
||||
this.youtubePlayer.playVideo();
|
||||
this.state = ChannelState.PLAYING;
|
||||
this.animateVolume();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,18 +113,6 @@ export default class Channel extends Vue {
|
|||
this.onUrlChange();
|
||||
}
|
||||
|
||||
private animateVolume() {
|
||||
clearInterval(this.animateVolumeInterval);
|
||||
const LFO_PERIOD = 3000;
|
||||
this.animateVolumeStart = new Date();
|
||||
this.animateVolumeInterval = setInterval(() => {
|
||||
if (this.animateVolumeStart) {
|
||||
const delta = new Date().getTime() - this.animateVolumeStart.getTime();
|
||||
this.volume = Math.sin(((delta % LFO_PERIOD) / LFO_PERIOD) * 2 * Math.PI) * 50 + 50;
|
||||
}
|
||||
}, 1000 / 60);
|
||||
}
|
||||
|
||||
private static fetchYoutubeTitle(videoId: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let url = `https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${videoId}`;
|
||||
|
|
Loading…
Reference in a new issue