Skip to content

Instantly share code, notes, and snippets.

@trisweb
Last active September 2, 2024 16:16
Show Gist options
  • Save trisweb/2c0c94273f653c81f34dbe8e85ad30e7 to your computer and use it in GitHub Desktop.
Save trisweb/2c0c94273f653c81f34dbe8e85ad30e7 to your computer and use it in GitHub Desktop.
Last.fm Now Playing Widget. Just add to a <script> and <style> tag on your site, or load from files, and call getNowPlaying() on page load.
.now-playing {
position: absolute;
right: 20px;
top: calc(50vh - (min(20vw, calc(100vh - 30px)) / 2, 400px));
z-index: 1001;
}
a.now-playing {
opacity: 1;
border: 0;
}
a.now-playing:hover img {
transform: scale(1.02) translateX(-0.2vw) perspective(500px) rotate3d(0, -1, 0.01, 6deg);
}
.now-playing .np-metadata > span {
display: block;
font-size: 14px;
letter-spacing: -0.01em;
font-weight: 500;
line-height: 180%;
text-align: right;
}
.now-playing .np-metadata {
margin-top: 16px;
opacity: 0;
transition: opacity 0.4s ease-out;
transition-delay: 0.5s;
}
.now-playing.loaded .np-metadata {
opacity: 1;
}
.now-playing img {
opacity: 0;
transform: scale(0.97) translateX(10px) perspective(500px);
border-radius: 2px;
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);
}
.now-playing.loaded img {
opacity: 1;
transform: perspective(500px) rotate3d(0, -1, 0, 4deg);
}
.now-playing .np-metadata .np-heading {
font-size: 11px;
font-weight: 900;
opacity: 0.5;
text-transform: uppercase;
letter-spacing: 0.11em;
}
.now-playing .np-metadata .np-roon {
width: 10px;
opacity: 0.5;
}
.now-playing .np-metadata .breather {
margin-right: 8px;
display: inline-block;
animation: pulsate 5s linear 0s infinite;
}
@keyframes pulsate {
0% { transform: scale(0.2, 0.2) rotate(0deg); opacity: 0.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; }
}
/* ********************************************************************** */
/* OLD SCHOOL CURRENT PLAYING STUFF */
var LFM_API = "https://ws.audioscrobbler.com/2.0/";
var LFM_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Get one at https://secure.last.fm/login?next=/api/account/create
var LFM_USER = "trisweb";
function getNowPlaying() {
var recentTracksUrl =
LFM_API+"?method=user.getrecenttracks&user="+LFM_USER+"&api_key="+LFM_KEY+"+&format=json&limit=1";
if (window.XMLHttpRequest) {
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
// All set
var response = JSON.parse(httpRequest.responseText);
console.log(response);
var 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.log('There was a problem with the last.fm request.');
}
}
};
httpRequest.open('GET', recentTracksUrl, true);
httpRequest.send();
}
var nowPlayingNode = null;
function renderNowPlaying(track) {
console.log(track);
if (nowPlayingNode) {
nowPlayingNode.remove();
}
nowPlayingNode = document.createElement("a");
nowPlayingNode.setAttribute("class", "now-playing");
var imageurl = track.image.slice(-1)[0]["#text"];
var nowPlayingImage = document.createElement("img");
nowPlayingImage.setAttribute("src", imageurl);
nowPlayingNode.appendChild(nowPlayingImage);
// Add more stuff to the display
var currently = track["@attr"] && track["@attr"].nowplaying == "true";
var metadata = document.createElement("div");
metadata.setAttribute("class", "np-metadata");
metadata.innerHTML =
"<span class=\"np-heading\">" + (currently ? "Now Playing" : "Latest Track") + "</span>" +
"<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\">"+track.date["#text"]+"</span>");
nowPlayingNode.appendChild(metadata);
nowPlayingNode.setAttribute("href", track.url);
document.body.appendChild(nowPlayingNode);
setTimeout(function() {
nowPlayingNode.setAttribute("class", "now-playing loaded");
}, 100);
}
@trisweb
Copy link
Author

trisweb commented Aug 22, 2020

This renders on the right-hand side of the page, scaled (somewhat responsively) to window width and height. But you can adjust the css at the top under .now-playing and the width under .now-playing img to change its position and size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment