My latest experiment is Needledrop, a turntable interface for playing music from YouTube. Enjoy chill vibes as you spin a virtual vinyl of your favorite album from YouTube. You can try it for yourself here:
With Needledrop, I went for the Dieter Rams school of design. It’s inspired by unapologetically skeuomorphic interfaces like Apple’s original Podcasts app, which featured a reel-to-reel tape machine. While I preferred the digitally native approach of Overcast for day-to-day use, Apple’s approach was visually striking.
Podcast’s interface wasn’t just veneer; the reels would progress as the podcast did, providing a subtle visual cue alongside the progress bar. Likewise in Needledrop, the tone arm travels across the record.
But Needledrop takes the interactivity one step further. Drop the needle and find your favorite track, more or less. It’s fuzzy and inexact, and emphasizes the continuous listening experience an album can be.
Pick Your Track
Click the “Track” button, paste the link to your favorite album from YouTube, and it’ll load on the platter. You can bookmark the URL for easy access and share it with friends.
A few quick picks:
- Beach House – Bloom
- Clairo – Best Of
- Joji – Nectar
- Radiohead – A Moon Shaped Pool
- Tyler the Creator – Flower Boy
Singles and podcasts work, and streams like lofi hip hop radio sorta work. And of course the needle drop.
Fun fact: podcasts have actually been pressed on vinyl.
Skeuomorphic Effects in CSS
Of course this post wouldn’t be complete if I didn’t geek out on implementation details.
First, to achieve spinning record, the following CSS animation was used. The 1.8 second duration corresponds with 33 1/3 rpm.
#record {
animation: spin 1.8s infinite linear;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
To pause the animation when the “Stop” button is tapped, I first tried animation: none;
. I quickly noticed that when you resume play, the animation will reset and the record jumps back to its initial position. To smooth out the animation, use this instead:
.pause #record {
animation-play-state: paused;
}
Needledrop can switch between 33 and 45 rpm. When changing the animation duration to account for this, I ran into a similar problem with the spinning animation being jerky. This happened even if I used a CSS variable like animation-duration: var(--duration);
.
To work around this, I nested two elements. When the mode is changed to 45 rpm, the second element activates a spin animation as well. After some quick maths, I set the duration of the second spin to 5.1428 seconds.
I also offset the rotation slightly with transform-origin
, creating a slight wobble effect.
To finish the record’s styles, I added grooves with:
background: repeating-radial-gradient(var(--record-color),
var(--record-groove-color) 3px,
var(--record-groove-color) 3px);
I also gave it a shine by positioning an element over the record with a conic background. A separate element was used so the shine wouldn’t rotate with the record.
background: conic-gradient(transparent 20deg,
rgba(255, 255, 255, .1) 40deg,
rgba(255, 255, 255, .1) 50deg,
transparent 60deg,
transparent 200deg,
rgba(255, 255, 255, .08) 220deg,
rgba(255, 255, 255, .08) 240deg,
transparent 250deg,
transparent 340deg);
To move the arm of the record player, I used transform: rotate(45deg);
and set a transition delay, calculating how long it should take for the arm to reach its final position in JavaScript.
YouTube API
Needledrop is built using the YouTube Player API.
The API makes it easy to speed up the video when set to 45 rpm, among other things:
player.setPlaybackRate(1.35);
Of course when you’re using a third-party API, you’re beholden to their terms of service. In this case, the key sections of Google’s TOS are:
You and your API Clients must not, and must not encourage, enable, or require others to:
6. modify, build upon, or block any portion or functionality of a YouTube player;
7. separate, isolate, or modify the audio or video components of any YouTube audiovisual content made available as part of, or in connection with, YouTube API Services. For example, you must not apply alternate audio tracks to videos;
8. promote separately the audio or video components of any YouTube audiovisual content made available as part of, or in connection with, the YouTube API Services;
9. create, include, or promote features that play content, including audio or video components, from a background player, meaning a player that is not displayed in the page, tab, or screen that the user is viewing;
So yeah. Hiding the video so only the audio track is used was definitely out. To the label it goes. As for the rest, we’re probably pushing it.
Anyway, much of digital design is influenced by its analog analogue. It was fun to bring that to the foreground with Needledrop.
As far as next steps, stay tuned for YouTube playlist and Spotify support.
Super fun! Thank you. Wish the clipping worked in Safari. Perhaps add to #record-inner…
overflow: hidden;
border-radius: 50%;
Thanks for the bug report. Your styles do the trick but unfortunately obscures part of the inner border.
-webkit-mask-image seems to have fixed it. Stack Overflow to the rescue!
Remember http://www.twoyoutubevideosandamotherfuckingcrossfader.com ? Now that would be worth reviving.
Love everything about this.
This is a neat idea and execution!
That aside, not gonna lie, I was looking for a grain effect toggle.
Good work! I want to know what my dad thinks of it.
Love this! Could you give us some more graphical options, as an example http://mytypewriter.org/ (another retro virtual simulation) gives several options for appearance
Loved this post. I am looking forward to more options.
As far as tracks, you can use this with any YouTube video by clicking the Track button and pasting in your link.
A froggy jumped on to the turntable. I really enjoyed froggy css game. Thanks!
THERE IS NO SOUND. WHY CAN’T I HEAR THE MUSIC? THERE IS NO SOUND WHEN I CLICK PLAY ON THE VIDEO? I THINK YOUR PLAYER IS BROKEN. CAN YOU LOOK INTO IT FOR ME? I’M USING EDGE WITH NO BLOCKERS AND NO RESTRICTIONS. IT’S REALLY ANNOYING.
To start the turntable, click the Start – Stop button. This should get the record spinning. Then drag the needle onto the record.
I just tested on Edge/Mac and it’s working on my end.
Fun. The 45 speed acts as a time compressor vs a speed changer. Which is to say, the pitch doesn’t change with the “speed change”, which is different from what would happen on a real turntable. But… if the primary utility for this is to play podcasts, that makes functional sense.
Can you make an offline one of these to play mp3s with?
I would really love it if we could have the option to play Youtube playlists where each track is one of the videos in the playlist. A lot of the albums are in that format. Really cool project tho!
I love records and I can’t wait.