add basic url input, styling
This commit is contained in:
parent
06ffaa02df
commit
8ebeeecb03
2 changed files with 77 additions and 11 deletions
62
src/App.vue
62
src/App.vue
|
@ -1,12 +1,27 @@
|
||||||
|
<!--suppress HtmlFormInputWithoutLabel -->
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
<div class="channels-wrapper">
|
||||||
<div class="channels">
|
<div class="channels">
|
||||||
<template v-for="i in N_CHANNELS">
|
<template v-for="i in N_CHANNELS">
|
||||||
<Channel :url="defaultMedia[i-1]" :volume="volumes[i-1]" :key="i" class="channel" ref="channels"/>
|
<Channel :name="names[i - 1]" :url="urls[i - 1]" :volume="volumes[i-1]"
|
||||||
|
:key="i"
|
||||||
|
class="channel" ref="channels"/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="channel-urls">
|
||||||
|
<div class="url-input" v-for="i in N_CHANNELS">
|
||||||
|
<label :for="`url-input-${names[i-1]}`">
|
||||||
|
{{names[i - 1]}}
|
||||||
|
</label>
|
||||||
|
<input :id="`url-input-${names[i-1]}`" type="text" v-model="urls[i - 1]"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="controls">
|
||||||
<button @click="start">START</button>
|
<button @click="start">START</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!--suppress JSUnusedLocalSymbols, JSMethodCanBeStatic -->
|
<!--suppress JSUnusedLocalSymbols, JSMethodCanBeStatic -->
|
||||||
|
@ -25,6 +40,8 @@ export default class App extends Vue {
|
||||||
private readonly LFO_DEPTH = 33;
|
private readonly LFO_DEPTH = 33;
|
||||||
private readonly LFO_OFFSET = 66;
|
private readonly LFO_OFFSET = 66;
|
||||||
|
|
||||||
|
private names = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu"];
|
||||||
|
private urls = Array(this.N_CHANNELS).fill("");
|
||||||
private volumes = Array(this.N_CHANNELS).fill(50);
|
private volumes = Array(this.N_CHANNELS).fill(50);
|
||||||
private animateVolumeStart?: Date;
|
private animateVolumeStart?: Date;
|
||||||
private animateVolumeInterval?: number;
|
private animateVolumeInterval?: number;
|
||||||
|
@ -33,6 +50,12 @@ export default class App extends Vue {
|
||||||
"https://www.youtube.com/watch?v=q76bMs-NwRk",
|
"https://www.youtube.com/watch?v=q76bMs-NwRk",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private mounted() {
|
||||||
|
this.defaultMedia.forEach((url, idx) => {
|
||||||
|
this.$set(this.urls, idx, url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private start() {
|
private start() {
|
||||||
(this.$refs.channels as Channel[]).forEach((channel) => {
|
(this.$refs.channels as Channel[]).forEach((channel) => {
|
||||||
channel.start();
|
channel.start();
|
||||||
|
@ -66,17 +89,52 @@ html, body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
|
font-family: monospace;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.channels-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channels {
|
.channels {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 2rem;
|
padding: 0 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel {
|
.channel {
|
||||||
margin: 0 1rem;
|
margin: 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.channel-urls {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-input {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-input label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 64px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-input input {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
<input class="volume" :disabled="state === 'unloaded'"
|
<input class="volume" :disabled="state === 'unloaded'"
|
||||||
type="range" min="0" max="100" v-model="volume"/>
|
type="range" min="0" max="100" v-model="volume"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="description">
|
||||||
|
<div class="name">{{name}}</div>
|
||||||
<div class="title">{{state === "loading" ? "Loading..." : title}}</div>
|
<div class="title">{{state === "loading" ? "Loading..." : title}}</div>
|
||||||
|
</div>
|
||||||
<div class="youtube-player" ref="ytpl"/>
|
<div class="youtube-player" ref="ytpl"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -32,6 +35,7 @@ enum ChannelState {
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class Channel extends Vue {
|
export default class Channel extends Vue {
|
||||||
|
@Prop() public name: string = "Channel";
|
||||||
@Prop() public volume: number = 50;
|
@Prop() public volume: number = 50;
|
||||||
@Prop() public url: string | undefined;
|
@Prop() public url: string | undefined;
|
||||||
private youtubePlayer?: YouTubePlayer;
|
private youtubePlayer?: YouTubePlayer;
|
||||||
|
@ -155,8 +159,7 @@ export default class Channel extends Vue {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-family: monospace;
|
font-size: 10px;
|
||||||
font-size: 8px;
|
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +173,7 @@ export default class Channel extends Vue {
|
||||||
|
|
||||||
|
|
||||||
.volume-wrapper {
|
.volume-wrapper {
|
||||||
--height: 200px;
|
--height: 180px;
|
||||||
--width: 30px;
|
--width: 30px;
|
||||||
height: var(--height);
|
height: var(--height);
|
||||||
width: var(--width);
|
width: var(--width);
|
||||||
|
@ -186,10 +189,15 @@ export default class Channel extends Vue {
|
||||||
transform: rotate(270deg);
|
transform: rotate(270deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin: .25em 1em;
|
margin: .25em 1em;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 3;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
Loading…
Reference in a new issue