Hey guys! Been a while since I last done a pen on here been super busy with work D: - I decided to create a nice little music player with ES2015! I hope you guys like it :D!
A Pen by Jack Thomson on CodePen.
| .player | |
| .player_inner | |
| .player_inner__artwork | |
| %h1.title | |
| %h2.song-name | |
| %p.time | |
| .player_inner__controls | |
| %i{'class' => 'material-icons prev'} skip_previous | |
| %i{'class' => 'material-icons play'} | |
| %i{'class' => 'material-icons next'} skip_next |
Hey guys! Been a while since I last done a pen on here been super busy with work D: - I decided to create a nice little music player with ES2015! I hope you guys like it :D!
A Pen by Jack Thomson on CodePen.
| class Player { | |
| constructor(autoplay, songs = []) { | |
| this.autoplay = autoplay; | |
| this.state = "paused"; | |
| this.songs = songs; | |
| this.audio = new Audio(); | |
| this.index = 0; | |
| this.timer; | |
| this.artwork = document.querySelector(".player_inner__artwork"); | |
| this.init(); | |
| } | |
| addElement(selector, val) { | |
| const el = document.querySelector(selector); | |
| val ? (el.innerHTML = val) : ""; | |
| } | |
| updateElement(el, newVal) { | |
| document.querySelector(el).innerHTML = newVal; | |
| } | |
| init() { | |
| this.artwork.style.background = "url(" + this.songs[0].artwork + ")"; | |
| this.artwork.style.backgroundSize = "cover"; | |
| this.artwork.style.backgroundPosition = "center"; | |
| if (this.autoplay) { | |
| this.addElement(".play", "stop"); | |
| this.state = "playing"; | |
| this.play(); | |
| } else { | |
| this.addElement(".play", "play_arrow"); | |
| this.updateElement(".title", this.songs[0].artist); | |
| this.updateElement(".song-name", this.songs[0].songName); | |
| } | |
| } | |
| play() { | |
| this.timeCount(); | |
| for (let i = this.index; i < this.songs.length; i++) { | |
| if (!this.songs[i].playing) { | |
| this.songs[i].playing = true; | |
| this.audio.src = this.songs[i].src; | |
| this.audio.play(); | |
| this.artwork.style.background = "url(" + this.songs[i].artwork + ")"; | |
| this.artwork.style.backgroundSize = "cover"; | |
| this.artwork.style.backgroundPosition = "center"; | |
| this.updateElement(".title", this.songs[i].artist); | |
| this.updateElement(".song-name", this.songs[i].songName); | |
| break; | |
| } | |
| } | |
| } | |
| timeCount() { | |
| let duration; | |
| let minutes; | |
| let seconds; | |
| let timeLeft; | |
| this.audio.addEventListener("loadeddata", () => { | |
| duration = this.audio.duration; | |
| minutes = Math.floor(duration / 60); | |
| seconds = Math.floor(duration - minutes * 60); | |
| timeLeft = minutes + ":" + seconds; | |
| }); | |
| this.timer = setInterval(() => { | |
| duration = duration - 1; | |
| minutes = Math.floor(duration / 60); | |
| seconds = Math.floor(duration - minutes * 60); | |
| if (seconds < 10) { | |
| seconds = "0" + seconds; | |
| } | |
| timeLeft = minutes + ":" + seconds; | |
| this.updateElement(".time", timeLeft); | |
| if (timeLeft === "0:00" && this.index !== this.songs.length - 1) { | |
| this.next(); | |
| } else if (timeLeft === "0:00" && this.index === this.songs.length - 1) { | |
| clearInterval(this.timer); | |
| } | |
| }, 1000); | |
| } | |
| pause() { | |
| for (let i = this.index; i < this.songs.length; i++) { | |
| if (this.songs[i].playing) { | |
| this.songs[i].playing = false; | |
| this.audio.pause(); | |
| clearInterval(this.timer); | |
| break; | |
| } | |
| } | |
| } | |
| next() { | |
| for (let i = this.index; i < this.songs.length; i++) { | |
| if (this.songs[i].playing && this.index !== this.songs.length - 1) { | |
| this.songs[i].playing = false; | |
| this.index++; | |
| clearInterval(this.timer); | |
| this.play(); | |
| break; | |
| } else if ( | |
| !this.songs[i].playing && | |
| this.index !== this.songs.length - 1 | |
| ) { | |
| this.index++; | |
| this.artwork.style.background = | |
| "url(" + this.songs[this.index].artwork + ")"; | |
| this.artwork.style.backgroundSize = "cover"; | |
| this.artwork.style.backgroundPosition = "center"; | |
| this.updateElement(".title", this.songs[this.index].artist); | |
| this.updateElement(".song-name", this.songs[this.index].songName); | |
| clearInterval(this.timer); | |
| } | |
| } | |
| } | |
| prev() { | |
| for (let i = this.index; i < this.songs.length; i++) { | |
| if (this.songs[i].playing && this.index === this.songs.length - 1) { | |
| this.songs[i].playing = false; | |
| this.index--; | |
| clearInterval(this.timer); | |
| this.play(); | |
| break; | |
| } else if ( | |
| !this.songs[i].playing && | |
| this.index === this.songs.length - 1 | |
| ) { | |
| this.index--; | |
| this.artwork.style.background = | |
| "url(" + this.songs[this.index].artwork + ")"; | |
| this.artwork.style.backgroundSize = "cover"; | |
| this.artwork.style.backgroundPosition = "center"; | |
| this.updateElement(".title", this.songs[this.index].artist); | |
| this.updateElement(".song-name", this.songs[this.index].songName); | |
| clearInterval(this.timer); | |
| } | |
| } | |
| } | |
| } | |
| /* Instantiate Player */ | |
| const player = new Player(true, [ | |
| { | |
| artist: "Tarik Ala", | |
| songName: "No No", | |
| artwork: "https://i1.sndcdn.com/avatars-000261408154-jm4ezq-t500x500.jpg", | |
| src: | |
| "https://cvws.icloud-content.com/B/AdazHEbTJnFyHOEEr5Lb5E9bz7YSAamRgU9RTPEQ0OsVAfdthXrLgktt/no-no.mp3?o=ArgaVn_vmEi-HGOsE2sCwLKCOIaIZcXBtVWtl3T6p9J6&v=1&x=3&a=BxiX8e489lm2Npi6RYcb6VNKn595A3LOPgEAAANjzj4&e=1509268899&k=4acXo2Gw_4x-MXBDsW5wPw&fl=&r=5f385859-b2c3-4b68-9840-ff1c9da95f7c-1&ckc=com.apple.clouddocs&ckz=com.apple.CloudDocs&p=43&s=30HkCWLVlE3P35iny0gFsz5ajhg&cd=i", | |
| playing: false | |
| }, | |
| { | |
| artist: "Enbe", | |
| songName: "Jealousy", | |
| artwork: "https://g1.img-dpreview.com/BFB47C21A22445B395157E60AC837759.jpg", | |
| src: | |
| "https://cvws.icloud-content.com/B/AQ5IwohxlgsoSokpUgaS5vFVQ288AYyDnNOAJwe7b4ARmK8n6AKCCWWk/jealousy.mp3?o=AgkiJsUamqWfirJNPEnjRtGUsRfrDFiYSX_rhgEdCCNI&v=1&x=3&a=B_oA1kcUY4J4VzmVPVHDiDF8mBO6A3POPgEAAANkzj4&e=1509268933&k=zu1NMxDDHT4SFrmc82S5yw&fl=&r=182014cf-f4bc-4edb-9f47-2fffc2cef40c-1&ckc=com.apple.clouddocs&ckz=com.apple.CloudDocs&p=43&s=FoFv0yA9PGuoohMit_nDaVko46A&cd=i", | |
| playing: false | |
| } | |
| ]); | |
| /* Music Player Buttons */ | |
| const playButton = document.querySelector(".play"); | |
| const nextButton = document.querySelector(".next"); | |
| const prevButton = document.querySelector(".prev"); | |
| /* Event Listeners */ | |
| playButton.addEventListener("click", () => { | |
| if (player.state === "paused") { | |
| player.play(); | |
| player.updateElement(".play", "stop"); | |
| player.state = "playing"; | |
| } else { | |
| player.pause(); | |
| player.updateElement(".play", "play_arrow"); | |
| player.state = "paused"; | |
| } | |
| }); | |
| nextButton.addEventListener("click", () => { | |
| player.next(); | |
| }); | |
| prevButton.addEventListener("click", () => { | |
| player.prev(); | |
| }); |
| // Variables | |
| $primary-color: #FFFBFE; | |
| $accent-color: #88D9E6; | |
| * { | |
| margin: 0; padding: 0; | |
| boz-sizing: border-box; | |
| font-family: 'Open Sans', sans-serif; | |
| } | |
| html,body { | |
| background: #F2F6F7; | |
| } | |
| .player { | |
| display: flex; | |
| width: 100vw; | |
| height: 100vh; | |
| justify-content: center; | |
| align-items: center; | |
| &_inner { | |
| background: $primary-color; | |
| width: 20em; | |
| height: 14em; | |
| &__artwork { | |
| height: 14em; | |
| box-shadow: 7px 5px 40px lighten(#000, 50%); | |
| border-radius: 3px; | |
| display: flex; | |
| flex-flow: column wrap; | |
| align-items: flex-start; | |
| padding: 1em; | |
| position: relative; | |
| h1, h2, p { | |
| text-transform: uppercase; | |
| color: #FFF; | |
| } | |
| h1 { | |
| font-size: 1.5em; | |
| font-weight: 700; | |
| background: #3A4454; | |
| padding: .2em; | |
| min-width: 5em; | |
| } | |
| h2 { | |
| font-size: .7em; | |
| font-weight: 300; | |
| background: $accent-color; | |
| padding: .6em; | |
| } | |
| p { | |
| padding: 1em 0; | |
| font-size: .6em; | |
| bottom: 0; | |
| position: absolute; | |
| } | |
| } | |
| &__controls { | |
| height: 3em; | |
| width: 24em; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| transform: translateY(-55%); | |
| i { | |
| color: #FFF; | |
| background: $accent-color; | |
| border-radius: 100%; | |
| font-size: 1em; | |
| padding: .5em; | |
| margin: auto .3em; | |
| cursor: pointer; | |
| &:nth-of-type(2) { | |
| font-size: 1.5em; | |
| } | |
| } | |
| } | |
| } | |
| } |