Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                mixin btn(bClass)
	button.btn(class=bClass)

//- .buttons
//- 	+btn('btn--big prev')
//- 	+btn('btn--big play')
//- 	+btn('btn--big next')
//- 	+btn('btn--big pause active')
//- 	+btn('btn--big playlist')
//- 	+btn('btn--big dots')
//- 	+btn('btn--big heart')
//- 	+btn('btn--big back')
//- 	br
//- 	+btn('btn--small prev')
//- 	+btn('btn--small play')
//- 	+btn('btn--small next')
//- 	+btn('btn--small pause active')
//- 	+btn('btn--small playlist')
//- 	+btn('btn--small dots')
//- 	+btn('btn--small heart')
//- 	+btn('btn--small back')

.app#app
	//- ul.tracks
	//- 	li.tracks__item(v-for='track in tracks')
	//- 		.tracks__info
	//- 			span {{track.artist}} - {{track.name}}
	.row.app__head
		+btn('btn--small back')
		+btn('btn--small playlist')
	.row.app__body
		.album
			.album__img(v-if="$index === currentTrackIndex" :style="{ backgroundImage: `url(${track.cover})` }"  v-for="(track, $index) in tracks" :key="$index")
			.album__info(v-if="currentTrack")
				h3.album__info-name {{ currentTrack.artist }}
				p.album__info-track {{ currentTrack.name }}
		.progress(ref="progress")
			.progress__count
				span {{ currentTime }}
				span {{ duration }}
			.progress__bar(@click="clickProgress")
				.progress__bar-current(:style="{ width : barWidth }")
				.progress__bar-pin(:style="{ left : barWidth }")
				
			
			
	.row.app__footer
		button.btn(class='prev btn--big' @click='prevTrack')

		button.btn(class='play btn--big' @click='play' :class='{pause: isTimerPlaying}')
		button.btn(class='next btn--big' @click='nextTrack')
		
              
            
!

CSS

              
                $img: 'https://sun9-2.userapi.com/c830709/v830709453/17f58c/vPCov8kW6Ns.jpg'
$gray: #6a6a6a
$g2: #84878A
$black: #050606
$dark: #18191D
$abbey: #47494B
$brightRed: #D11302
$dRed: #A30D02
$RedOxide: #5D0F04
$accent: #E8550C
$RoseBud: #F5A691
$white: #fff
$lemon: #f9ca24


$gr: linear-gradient(120deg, $abbey 0%, $dark 100%)
$gr2: linear-gradient(120deg, $accent 0%, lighten($accent, 10) 100%)
$gr3: linear-gradient(45deg, $brightRed 0%, $lemon 100%)


*, *::before, *::after
	padding: 0
	margin: 0
	box-sizing: border-box
body
	font-size: 28px
	background-color: #26282B

//button
.btn
	cursor: pointer
	position: relative
	display: inline-block
	outline: none
	border-radius: 50px
	background-color: $black
	background-image: $gr
	color: $g2
	text-align: center
	border-style: solid
	border-color: lighten($dark, 10)
	font-family: 'Font Awesome 5 Free'
	font-weight: 600
	text-align: center
	&::before
		user-select: none
		position: absolute
		top: 50%
		transform: translate(-50%, -50%)
	&--big
		font-size: 1.1rem
		height: 80px
		width: 80px
		border-width: 3px
		line-height: 1
		box-shadow: -3px -3px 20px darken($gray, 6), 5px 5px 20px $black
		&:active, &.active
			box-shadow: inset 10px 10px 20px rgba($brightRed, .5), -3px -3px 20px darken($gray, 6), 5px 5px 20px $black

	&--small
		box-shadow: -3px -3px 15px $gray, 3px 3px 15px $black
		font-size: .6rem
		height: 50px
		width: 50px
		border-width: 2px
		line-height: 1
		&:active, &.active
			box-shadow: inset 10px 10px 20px rgba($brightRed, .5), -3px -3px 15px $gray, 3px 3px 15px $black
	&:active, &.active
		border-color: $accent
		background-image: $gr2
		color: $white


	&.play
		margin: 0 20px
		&::before
			content: '\f04b'
			left: 50%
		&.pause
			border-color: $accent
			background-image: $gr2
			color: $white
			box-shadow: inset 10px 10px 20px rgba($brightRed, .5), -3px -3px 20px darken($gray, 6), 5px 5px 20px $black
			&::before
				content: '\f04c'
				left: 50%

	&.pause
		&::before
			content: '\f04c'
			left: 50%

	&.dots
		&::before
			content: '\f141'
			left: 50%

	&.playlist
		&::before
			content: '\f0c9'
			left: 50%

	&.heart
		&::before
			content: '\f004'
			left: 49%

	&.prev
		&::before
			content: '\f04a'
			left: 48%

	&.next
		&::before
			content: '\f04e'
			left: 50%

	&.back
		&::before
			content: '\f053'
			left: 48%

.app
	padding: 35px
	max-width: 400px
	margin: 20px auto
	display: flex
	flex-direction: column
	align-items: center
	background-image: linear-gradient(#343A3F 0%, #232528 100%)
	border: 1px solid darken($g2, 30)
	border-radius: 50px
	box-shadow: 5px 5px 35px $dark
	&__head
		justify-content: space-between
	&__body
		margin: 30px 0 50px
		flex-direction: column
	&__footer
		justify-content: center
		margin-bottom: 40px

.row
	display: flex
	width: 100%

.album
	align-self: center
	margin-bottom: 50px
	&__img
		border: 10px solid $dark
		height: 300px
		width: 300px
		border-radius: 100%
		box-shadow: -5px -5px 25px darken($gray, 15), 5px 5px 25px $black
		background-image: url($img)
		background-repeat: no-repeat
		background-position: center
		background-size: cover
	&__info
		margin-top: 50px
		text-align: center
		color: #A7A8AA
		&-name
			font-size: 36px
			padding-bottom: 10px
		&-track
			padding-top: 5px
			font-size: 16px

.progress
	position: relative
	margin-bottom: 30px
	&__count
		width: 100%
		display: flex
		justify-content: space-between
		font-size: 14px
		color: $gray
	&__bar
		position: relative
		margin-top: 25px
		border-radius: 50px
		width: 100%
		height: 8px
		background-color: lighten($dark, 5)
		cursor: pointer
		&::before
			content: ''
			position: absolute
			height: 100%
			width: 100%
			box-sizing: border-box
			border-bottom: 2px solid $gray
			border-left: 2px solid $gray
			border-right: 1px solid $gray
			z-index: 1
			border-radius: 50px
			box-shadow: inset 5px 3px 5px #000
		
		&-current
			transition: all .25s ease
			position: absolute
			background-image: $gr3
			height: calc(100% - 2px)
			width: 0%
			z-index: 3
			bottom: 1px
			left: 2px
			border-radius: 50px
			box-shadow: inset 0px 2px 3px rgba($dark, .5)
		&-pin
			height: 30px
			width: 30px
			border-radius: 50px
			position: absolute
			left: 0%
			transition: all .25s ease
			top: 50%
			transform: translateY(-50%)
			z-index: 10
			background-image: $gr
			box-shadow: -5px -5px 15px darken($gray, 15), 3px 3px 15px $black, inset -3px -3px 5px $dark
			&::after
				content: ''
				position: absolute
				border-radius: 50px
				top: 50%
				left: 50%
				transform: translate(-50%, -50%)
				height: 35%
				width: 35%
				background-color: $lemon
				box-shadow: -5px -5px 12px $dark, 5px 5px 12px $gray, inset 2px 2px 5px lighten($gray, 5)
.tracks
	position: absolute
              
            
!

JS

              
                /*
js-code by - https://codepen.io/JavaScriptJunkie/pen/qBWrRyg?editors=1000
design by Filip Legierski.
design: https://dribbble.com/shots/9338617-Simple-Music-Player
*/

new Vue({
  el: "#app",
  data() {
    return {
      audio: null,
      circleLeft: null,
      barWidth: null,
      duration: null,
      currentTime: null,
      isTimerPlaying: false,
      tracks: [
				{
          name: "Genius ft. Sia, Diplo, Labrinth",
          artist: "LSD",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/6.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/6.mp3",
          url: "https://www.youtube.com/watch?v=HhoATZ1Imtw",
          favorited: false
        },
				{
          name: "Extreme Ways",
          artist: "Moby",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/3.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/3.mp3",
          url: "https://www.youtube.com/watch?v=ICjyAe9S54c",
          favorited: false
        },
        {
          name: "Everybody Knows",
          artist: "Leonard Cohen",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/2.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/2.mp3",
          url: "https://www.youtube.com/watch?v=Lin-a2lTelg",
          favorited: true
        },

        {
          name: "Butterflies",
          artist: "Sia",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/4.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/4.mp3",
          url: "https://www.youtube.com/watch?v=kYgGwWYOd9Y",
          favorited: false
        },
        {
          name: "The Final Victory",
          artist: "Haggard",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/5.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/5.mp3",
          url: "https://www.youtube.com/watch?v=0WlpALnQdN8",
          favorited: true
        },
        {
          name: "The Comeback Kid",
          artist: "Lindi Ortega",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/7.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/7.mp3",
          url: "https://www.youtube.com/watch?v=me6aoX0wCV8",
          favorited: true
        },
        {
          name: "Overdose",
          artist: "Grandson",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/8.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/8.mp3",
          url: "https://www.youtube.com/watch?v=00-Rl3Jlx-o",
          favorited: false
        },
				{
          name: "Mekanın Sahibi",
          artist: "Norm Ender",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/1.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/1.mp3",
          url: "https://www.youtube.com/watch?v=z3wAjJXbYzA",
          favorited: false
        },
        {
          name: "Rag'n'Bone Man",
          artist: "Human",
          cover: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/img/9.jpg",
          source: "https://raw.githubusercontent.com/muhammederdem/mini-player/master/mp3/9.mp3",
          url: "https://www.youtube.com/watch?v=L3wKzyIN1yk",
          favorited: false
        }
      ],
      currentTrack: null,
      currentTrackIndex: 0,
      transitionName: null
    };
  },
  methods: {
    play() {
      if (this.audio.paused) {
        this.audio.play();
        this.isTimerPlaying = true;
      } else {
        this.audio.pause();
        this.isTimerPlaying = false;
      }
    },
    generateTime() {
      let width = (100 / this.audio.duration) * this.audio.currentTime;
      this.barWidth = width + "%";
      this.circleLeft = width + "%";
      let durmin = Math.floor(this.audio.duration / 60);
      let dursec = Math.floor(this.audio.duration - durmin * 60);
      let curmin = Math.floor(this.audio.currentTime / 60);
      let cursec = Math.floor(this.audio.currentTime - curmin * 60);
      if (durmin < 10) {
        durmin = "0" + durmin;
      }
      if (dursec < 10) {
        dursec = "0" + dursec;
      }
      if (curmin < 10) {
        curmin = "0" + curmin;
      }
      if (cursec < 10) {
        cursec = "0" + cursec;
      }
      this.duration = durmin + ":" + dursec;
      this.currentTime = curmin + ":" + cursec;
    },
    updateBar(x) {
      let progress = this.$refs.progress;
      let maxduration = this.audio.duration;
      let position = x - progress.offsetLeft;
      let percentage = (100 * position) / progress.offsetWidth;
      if (percentage > 100) {
        percentage = 100;
      }
      if (percentage < 0) {
        percentage = 0;
      }
      this.barWidth = percentage + "%";
      this.circleLeft = percentage + "%";
      this.audio.currentTime = (maxduration * percentage) / 100;
      this.audio.play();
    },
    clickProgress(e) {
      this.isTimerPlaying = true;
      this.audio.pause();
      this.updateBar(e.pageX);
    },
    prevTrack() {
      this.transitionName = "scale-in";
      this.isShowCover = false;
      if (this.currentTrackIndex > 0) {
        this.currentTrackIndex--;
      } else {
        this.currentTrackIndex = this.tracks.length - 1;
      }
      this.currentTrack = this.tracks[this.currentTrackIndex];
      this.resetPlayer();
    },
    nextTrack() {
      this.transitionName = "scale-out";
      this.isShowCover = false;
      if (this.currentTrackIndex < this.tracks.length - 1) {
        this.currentTrackIndex++;
      } else {
        this.currentTrackIndex = 0;
      }
      this.currentTrack = this.tracks[this.currentTrackIndex];
      this.resetPlayer();
    },
    resetPlayer() {
      this.barWidth = 0;
      this.circleLeft = 0;
      this.audio.currentTime = 0;
      this.audio.src = this.currentTrack.source;
      setTimeout(() => {
        if(this.isTimerPlaying) {
          this.audio.play();
        } else {
          this.audio.pause();
        }
      }, 300);
    },
    favorite() {
      this.tracks[this.currentTrackIndex].favorited = !this.tracks[
        this.currentTrackIndex
      ].favorited;
    }
  },
  created() {
    let vm = this;
    this.currentTrack = this.tracks[0];
    this.audio = new Audio();
    this.audio.src = this.currentTrack.source;
    this.audio.ontimeupdate = function() {
      vm.generateTime();
    };
    this.audio.onloadedmetadata = function() {
      vm.generateTime();
    };
    this.audio.onended = function() {
      vm.nextTrack();
      this.isTimerPlaying = true;
    };

    // this is optional (for preload covers)
    for (let index = 0; index < this.tracks.length; index++) {
      const element = this.tracks[index];
      let link = document.createElement('link');
      link.rel = "prefetch";
      link.href = element.cover;
      link.as = "image"
      document.head.appendChild(link)
    }
  }
});

              
            
!
999px

Console