Skip to content

Instantly share code, notes, and snippets.

@jeffbyrnes
Forked from trisweb/lastfm_nowplaying.css
Last active February 26, 2021 00:37
Show Gist options
  • Save jeffbyrnes/916df621bca2f79b34afdddcdab713fc to your computer and use it in GitHub Desktop.
Save jeffbyrnes/916df621bca2f79b34afdddcdab713fc to your computer and use it in GitHub Desktop.
Last.fm Now Playing Widget. Add to a <script> and <style> tag on your site, or load from files.
/* ********************************************************************** */
/* OLD SCHOOL CURRENT PLAYING STUFF */
const LFM_API = 'https://ws.audioscrobbler.com/2.0/'
// Get one at https://secure.last.fm/login?next=/api/account/create
const LFM_KEY = 'ce8a26c8204cd9994cb27278d682efe3'
const LFM_USER = 'jeffbyrnes'
async function getNowPlaying () {
const recentTracksUrl = `${LFM_API}?method=user.getrecenttracks&user=${LFM_USER}&api_key=${LFM_KEY}+&format=json&limit=1`
let httpRequest
try {
httpRequest = await fetch(recentTracksUrl)
} catch (error) {
console.error(`Something’s gone wrong: ${error.message}`)
}
if (httpRequest.ok) {
const response = await httpRequest.json()
console.log(response)
const currentTrack = response.recenttracks.track[0]
// Check if it's the same, if not then rerender
if (
!window.nowPlaying ||
window.nowPlaying.mbid !== currentTrack.mbid
) {
window.nowPlaying = currentTrack
renderNowPlaying(currentTrack)
}
setTimeout(getNowPlaying, 60 * 1000)
} else {
console.error(`HTTP error! status: ${httpRequest.status}`)
}
}
function renderNowPlaying (track) {
const currently = track['@attr'] && track['@attr'].nowplaying === 'true'
const imageurl = track.image.slice(-1)[0]['#text']
const date = new Date(track.date.uts * 1000);
const datetime = date.toLocaleString()
let nowPlaying = null
let nowPlayingContainer = null
console.log(track)
if (nowPlaying) {
nowPlaying.remove()
}
nowPlayingContainer = document.getElementsByClassName('now-playing-container')[0]
nowPlaying = document.createElement('a')
nowPlaying.className = 'now-playing'
nowPlaying.innerHTML = `<h1 class="np-heading">${(currently ? 'Now Playing' : 'Latest Track')}</h1>`
const nowPlayingImage = document.createElement('img')
nowPlayingImage.src = imageurl
nowPlaying.append(nowPlayingImage)
// Add more stuff to the display
const metadata = document.createElement('div')
metadata.setAttribute('class', 'np-metadata')
metadata.innerHTML =
`<span class="np-title"><strong>${track.name}</strong></span>` +
`<span class="np-artist">${track.artist['#text']}</span>` +
(currently
? '<span class="np-date"><span class="breather">◉</span> Currently Playing</span>'
: `<span class="np-date">${datetime}</span>`)
nowPlaying.append(metadata)
nowPlaying.setAttribute('href', track.url)
nowPlayingContainer.append(nowPlaying)
setTimeout(function () {
nowPlaying.setAttribute('class', 'now-playing loaded')
}, 100)
}
window.addEventListener('load', (event) => {
getNowPlaying()
})
.now-playing-container {
padding: 2.3125rem 0;
}
.now-playing {
opacity: 1;
border: 0;
&:hover img {
transform: scale(1.02) translateX(-0.2vw) perspective(500px) rotate3d(0, -1, 0.01, 6deg);
}
img {
opacity: 0;
transform: scale(0.97) translateX(10px) perspective(500px);
border-radius: 2px;
// Sass is case-sensitive, so we uppercase min() to bypass name collisions
// https://css-tricks.com/when-sass-and-new-css-features-collide/#the-solution
width: Min(20vw, calc(100vh - 30px), 400px);
box-shadow: 0 0 25px rgba(0, 0, 0, 0.2);
transition: all 1s cubic-bezier(0.13, 0.95, 0, 1), transform 2s cubic-bezier(0.13, 0.95, 0, 1);
}
&.loaded img {
opacity: 1;
transform: perspective(500px) rotate3d(0, -1, 0, 4deg);
}
.np-metadata {
margin-top: 1rem;
opacity: 0;
transition: opacity 0.4s ease-out;
transition-delay: 0.5s;
> span {
display: block;
letter-spacing: -0.01em;
font-weight: 500;
line-height: 1.8;
}
.np-roon {
width: 0.625rem;
opacity: 0.5;
}
.breather {
margin-right: 8px;
display: inline-block;
animation: pulsate 5s linear 0s infinite;
}
}
&.loaded .np-metadata {
opacity: 1;
}
}
@keyframes pulsate {
0% {
transform: scale(0.2, 0.2) rotate(0deg);
opacity: 0;
}
50% {
transform: scale(1, 1) rotate(50deg);
opacity: 1;
}
80% {
transform: scale(1.8, 1.8) rotate(80deg);
opacity: 0.2;
}
100% {
transform: scale(4, 4) rotate(100deg);
opacity: 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment