basic impl.; no websockets yet!
This commit is contained in:
commit
d8aa765bf7
5 changed files with 151 additions and 0 deletions
BIN
public/default-artwork.png
Normal file
BIN
public/default-artwork.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
23
public/index.html
Normal file
23
public/index.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title></title>
|
||||||
|
<link href="main.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<div id="music-ticker">
|
||||||
|
<div class="artwork-container">
|
||||||
|
<img src="default-artwork.png" alt="" width="64" height="64" id="artwork">
|
||||||
|
</div>
|
||||||
|
<div id="metadata">
|
||||||
|
<h1 id="title">Unknown Track</h1>
|
||||||
|
<p id="artist-album">Unknown Artist • Unknown Album</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="module" src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
87
public/main.css
Normal file
87
public/main.css
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
:root {
|
||||||
|
--ticker-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
background: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
#music-ticker {
|
||||||
|
/* width: fit-content; */
|
||||||
|
max-width: var(--ticker-width);
|
||||||
|
margin: 32px;
|
||||||
|
padding: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
&.outline {
|
||||||
|
border: 1px solid white;
|
||||||
|
outline: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artwork-container {
|
||||||
|
width: 64px;
|
||||||
|
min-width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#metadata {
|
||||||
|
min-width: 0;
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 1px 1px 0 #000a;
|
||||||
|
overflow-x: clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
width: fit-content;
|
||||||
|
min-width: 0;
|
||||||
|
margin: -2px 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: fit-content;
|
||||||
|
min-width: 0;
|
||||||
|
margin: -2px 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marquee {
|
||||||
|
animation: 20s ease-in-out infinite marquee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes marquee {
|
||||||
|
20% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
transform: translateX(calc(-100% + var(--ticker-width) - 74px));
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
transform: translateX(calc(-100% + var(--ticker-width) - 74px));
|
||||||
|
}
|
||||||
|
}
|
39
public/main.js
Normal file
39
public/main.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import Stateful from './silver.min.js';
|
||||||
|
|
||||||
|
const musicMeta = new Stateful({
|
||||||
|
artworkURL: 'https://arimelody.space/uploads/musicart/free2play.png',
|
||||||
|
title: 'falling asleep - house version',
|
||||||
|
artist: 'ari melody',
|
||||||
|
album: 'free2play',
|
||||||
|
});
|
||||||
|
|
||||||
|
const elArtwork = document.getElementById('artwork');
|
||||||
|
const elTitle = document.getElementById('title');
|
||||||
|
const elArtistAlbum = document.getElementById('artist-album');
|
||||||
|
const elMetadata = document.getElementById('metadata');
|
||||||
|
|
||||||
|
function setMetadata(artworkURL, title, artist, album) {
|
||||||
|
musicMeta.set({ artworkURL, title, artist, album });
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('readystatechange', () => {
|
||||||
|
musicMeta.onUpdate(value => {
|
||||||
|
elArtwork.src = value.artworkURL;
|
||||||
|
elTitle.innerText = value.title;
|
||||||
|
elArtistAlbum.innerText = `${value.artist} • ${value.album}`;
|
||||||
|
document.title = `Now playing: ${value.artist} - ${value.title}`;
|
||||||
|
console.log(`Now playing: ${value.artist} - ${value.title}`);
|
||||||
|
|
||||||
|
const maxWidth = elMetadata.getBoundingClientRect().width;
|
||||||
|
elTitle.classList.remove('marquee');
|
||||||
|
elArtistAlbum.classList.remove('marquee');
|
||||||
|
if (elTitle.getBoundingClientRect().width > maxWidth) {
|
||||||
|
elTitle.classList.add('marquee');
|
||||||
|
}
|
||||||
|
if (elArtistAlbum.getBoundingClientRect().width > maxWidth) {
|
||||||
|
elArtistAlbum.classList.add('marquee');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.setMetadata = setMetadata;
|
2
public/silver.min.js
vendored
Normal file
2
public/silver.min.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export default class Stateful{#e;#t=[];constructor(e){this.#e=e}get(){return this.#e}set(e){let t=this.#e;this.#e=e;for(let s in this.#t)this.#t[s](e,t)}update(e){this.set(e(this.#e))}onUpdate(e){return this.#t.push(e),e}removeListener(e){this.#t=this.#t.filter((t=>t!==e))}}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue