JSFiddle - React, Tailwind, and code Playground
HTML
<link href="https://fonts.googleapis.com/css2?family=Permanent+Marker&display=swap" rel="stylesheet">
<svg viewBox="2.5 2.5 95 60" xmlns="http://www.w3.org/2000/svg">
<path id="body" d="M5 5 95 5 95 55 5 55 z" stroke="#222" stroke-width="5" stroke-linecap="square" stroke-linejoin="round" fill="#222"></path>
<path id="trapezoid" d="M18 57 21 45 79 45 82 57 z" stroke="#333" fill="#333"></path>
<path id="label" d="M10 10 90 10 90 40 10 40 z" stroke="#eee" stroke-width="5" stroke-linecap="square" stroke-linejoin="round" fill="#eee"></path>
<!-- rainbow -->
<path d="M7.5 21.5 92.5 21.5 92.5 38.5 7.5 38.5 z" fill="red"></path>
<path d="M7.5 24.9 92.5 24.9 92.5 38.5 7.5 38.5 z" fill="orange"></path>
<path d="M7.5 28.4 92.5 28.4 92.5 38.5 7.5 38.5 z" fill="yellow"></path>
<path d="M7.5 31.8 92.5 31.8 92.5 38.5 7.5 38.5 z" fill="green"></path>
<path d="M7.5 35.2 92.5 35.2 92.5 38.5 7.5 38.5 z" fill="blue"></path>
<path d="M20 24 80 24 80 36 20 36 z" stroke="#333" stroke-width="5" stroke-linecap="square" stroke-linejoin="round" fill="#333"></path>
<clipPath id="window">
<path d="M40 24 60 24 60 36 40 36 z"></path>
</clipPath>
<path d="M40 24 60 24 60 36 40 36 z" fill="#eee" style="clip-path: url(#window)"></path>
<circle id="left-spool" cx="30" cy="30" r="25.45" style="clip-path: url(#window);" />
<circle id="right-spool" cx="70" cy="30" r="0" fill="#000" style="clip-path: url(#window);" />
<circle cx="30" cy="30" r="5" fill="#aaa" />
<circle cx="70" cy="30" r="5" fill="#aaa" />
<circle cx="25" cy="54" r="2.2" fill="#eee" />
<circle cx="75" cy="54" r="2.2" fill="#eee" />
<path d="M35 51 37 51 37 53 35 53 z" stroke="#eee" stroke-width="2" stroke-linecap="square" stroke-linejoin="round" fill="#eee"></path>
<path d="M65 51 63 51 63 53 65 53 z" stroke="#eee" stroke-width="2" stroke-linecap="square" stroke-linejoin="round" fill="#eee"></path>
<!-- lines -->
<line x1="12.5" y1="12.5" x2="87.5" y2="12.5" stroke="#aaa"...
CSS
@keyframes wobble1 {
from {
cx: 69.8;
}
to {
cx: 70.2;
}
}
@keyframes wobble2 {
from {
cx: 29.8;
}
to {
cx: 30.2;
}
}
#left-spool {
animation: 1s infinite alternate wobble2;
animation-play-state: paused;
}
#right-spool {
animation: 1.3s infinite alternate wobble1;
animation-play-state: paused;
}
.label {
font-size: 5px;
font-family: 'Permanent Marker', cursive;
}
audio {
width: 100%;
}
JavaScript
var audio = document.querySelector("audio");
audio.addEventListener("play", (event) => {
console.log("animating");
document.getElementById("left-spool").style.animationPlayState = "running";
document.getElementById("right-spool").style.animationPlayState = "running";
});
audio.addEventListener("pause", (event) => {
document.getElementById("left-spool").style.animationPlayState = "paused";
document.getElementById("right-spool").style.animationPlayState = "paused";
});
audio.addEventListener("ended", (event) => {
document.getElementById("left-spool").style.animationPlayState = "paused";
document.getElementById("right-spool").style.animationPlayState = "paused";
});
audio.addEventListener("timeupdate", (event) => {
var progress = audio.currentTime / audio.duration;
var totalArea = 2035;
var leftRadius = Math.sqrt((totalArea * (1 - progress)) / 3.1415);
var rightRadius = Math.sqrt((totalArea * progress) / 3.1415);
document.getElementById("left-spool").setAttribute("r", leftRadius);
document.getElementById("right-spool").setAttribute("r", rightRadius);
});
document.getElementById("artist").textContent = audio.dataset.artist;
document.getElementById("title").textContent = `- ${audio.dataset.title} -`;
document.getElementById("album").textContent = `(${audio.dataset.album})`;
var svg = document.querySelector("svg");
svg.addEventListener("click", (event) => {
if (audio.paused) {
audio.play();
} else {
audio.pause();
}
})