A Pen by Jeremy Karlsson on CodePen.
Created
July 28, 2015 14:21
-
-
Save zet4/fe8fb3a7b7c1a39f6081 to your computer and use it in GitHub Desktop.
MwwqKo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="player"> | |
<input type="file" id="file-open"> | |
<audio id="audio"></audio> | |
<div class="backdrop"> | |
<img src="https://i1.sndcdn.com/artworks-000108737757-qh5ga7-t500x500.jpg" alt="Cover Art" alt="backdrop"> | |
</div> | |
<header class="main-header"> | |
<div class="left"> | |
<button id="open-file-button"> | |
<span class="fa fa-folder-open-o"></span> | |
</button> | |
<button> | |
<span class="fa fa-list"></span> | |
</button> | |
</div> | |
<div class="center"> | |
<div class="play-icon play material-click" id="play-pause-button"> | |
<div class="first"></div> | |
<div class="second"></div> | |
</div> | |
</div> | |
<div class="right"> | |
<button> | |
<span class="fa fa-close"></span> | |
</button> | |
</div> | |
</header> | |
<main> | |
<figure class="cover-art"> | |
<canvas class="music-visuals"></canvas> | |
<img src="https://i1.sndcdn.com/artworks-000108737757-qh5ga7-t500x500.jpg" alt="Cover Art"> | |
</figure> | |
<div class="song-info"> | |
<span class="song-title">Godzilla 2015</span> | |
<span class="song-artist">K-391</span> | |
</div> | |
</main> | |
<footer class="controls"> | |
<div class="waveform-wrap"> | |
<div class="foreground-waveform" id="wav"> | |
</div> | |
<div class="background-waveform"> | |
</div> | |
</div> | |
</footer> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var audio = $('#audio')[0]; | |
$('#play-pause-button').on('click', function() { | |
if (audio.paused) { | |
audio.play(); | |
} else { | |
audio.pause(); | |
} | |
}); | |
$('#open-file-button').on('click', function() { | |
$('#file-open').click(); | |
}); | |
$('#audio').on('play', function() { | |
$('.play-icon').addClass('pause'); | |
MusicVisuals.start(); | |
}); | |
$('#audio').on('pause', function() { | |
$('.play-icon').removeClass('pause'); | |
MusicVisuals.stop(); | |
}); | |
$('#audio').on('timeupdate', function() { | |
var percentage = (audio.currentTime / audio.duration) * 100; | |
$('.foreground-waveform').css('width', 'calc(' + percentage + 'vw + 1.35px)'); | |
}); | |
$('.waveform-wrap').on('click', function(event) { | |
audio.currentTime = audio.duration * (event.pageX / window.innerWidth); | |
}); | |
function setMetadata(title, artist, cover) { | |
$('.song-title').text(title); | |
$('.song-artist').text(title); | |
$('.cover-art img').attr('src', cover); | |
$('.backdrop img').attr('src', cover); | |
} | |
$('#file-open').on('change', function(event) { | |
var file = event.target.files[0]; | |
audio.src = URL.createObjectURL(file); | |
audio.play(); | |
var reader = new FileReader(); | |
reader.onload = function(event) { | |
var settings = { | |
bar: { | |
align:'bottom', | |
width: 1, | |
gap: 0 | |
}, | |
waveform: { | |
color: '#fff', | |
width: window.innerWidth, | |
height: 50 | |
} | |
}; | |
new WaveformGenerator(event.target.result, settings).then(function(s) { | |
$('.background-waveform').html(s); | |
$('.foreground-waveform').html(s); | |
$('.foreground-waveform svg')[0].id = $('.foreground-waveform svg')[0].id + '2'; | |
$('.foreground-waveform svg style').text('svg#'+$('.foreground-waveform svg')[0].id+' path{stroke: black}'); | |
}); | |
}; | |
reader.readAsArrayBuffer(file); | |
var tagReader = new FileReader(); | |
tagReader.onloadend = function(e) { | |
ID3.loadTags(file.urn, function() { | |
var tags = new ID3.getAllTags(file.urn); | |
var image = tags.picture; | |
var cover = ''; | |
if (image) { | |
var base64String = ''; | |
for (var i = 0; i < image.data.length; i++) { | |
base64String += String.fromCharCode(image.data[i]); | |
} | |
cover = "data:" + image.format + ";base64," + window.btoa(base64String); | |
} | |
setMetadata(tags.title, tags.artist, cover); | |
}, { | |
tags: ["title", "artist", "picture", "album", "year"], | |
dataReader: FileAPIReader(file) | |
}); | |
}; | |
tagReader.readAsDataURL(file); | |
}); | |
// Start of Music Visuals | |
var canvas = document.getElementsByTagName('canvas')[0]; | |
var canvasContext = canvas.getContext('2d'); | |
canvas.width = window.innerWidth; | |
canvas.height = 50; | |
var audioContext = new window.AudioContext(); | |
var source = audioContext.createMediaElementSource(audio); | |
var analyser = audioContext.createAnalyser(); | |
source.connect(analyser); | |
analyser.connect(audioContext.destination); | |
analyser.fftSize = 2048; | |
analyser.minDecibels = -90; | |
analyser.maxDecibels = 0; | |
var bufferLength = analyser.frequencyBinCount * 0.8; | |
var frequencyData = new Uint8Array(bufferLength); | |
var circle = document.querySelector('.cover-art img'); | |
var ScaleBar = { | |
min: 0, | |
max: canvas.height, | |
sum: 0, | |
get: function(fromMin, fromMax, valueIn) { | |
var toMin = ScaleBar.min, | |
toMax = ScaleBar.max; | |
fromMin = ScaleBar.sum * fromMin; | |
fromMin = (fromMax * 0.5); | |
var result = ((toMax - toMin) * (valueIn - fromMin)) / (fromMax - fromMin) + toMin; | |
return result; | |
} | |
}; | |
var MusicVisuals = { | |
call: null, | |
start: function() { | |
canvasContext.clearRect(0, 0, canvas.width, canvas.height); | |
analyser.getByteFrequencyData(frequencyData); | |
var frequencyWidth = (canvas.width / bufferLength) * 2, frequencyHeight = 0, x = 0, scales = [], shadows = [], fd = []; | |
var fdMin = Math.min.apply(Math,frequencyData); | |
var fdMax = Math.max.apply(Math,frequencyData); | |
for(var increment = 0; increment < bufferLength; increment++) { | |
frequencyHeight = frequencyData[increment] * (canvas.height / 250); | |
if (increment < 15) { | |
scales.push(frequencyHeight / 50); | |
} else if (increment > (bufferLength / 2)) { | |
shadows.push(frequencyHeight * 3); | |
} | |
fd.push(frequencyData[increment]); | |
frequencyHeight = ScaleBar.get(fdMin, fdMax, frequencyData[increment]); | |
canvasContext.fillStyle = 'rgba(255,255,255,.3)'; | |
var y = canvas.height - frequencyHeight; | |
canvasContext.fillRect(x, y, frequencyWidth, frequencyHeight); | |
x += frequencyWidth-0.2; | |
} | |
var sc = scales.reduce(function(pv, cv) { return pv + cv; }, 0) / scales.length; | |
ScaleBar.sum = fd.reduce(function(pv, cv) { return pv + cv; }, 0) / fd.length; | |
circle.style.transform = 'scale('+ (sc > 1 ? sc : 1) +')'; | |
circle.style.boxShadow = '0 0 ' + shadows.reduce(function(pv, cv) { return pv + cv; }, 0) / shadows.length + 'px white'; | |
MusicVisuals.call = requestAnimationFrame(MusicVisuals.start); | |
}, | |
stop: function() { | |
cancelAnimationFrame(MusicVisuals.call); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="//cdnjs.cloudflare.com/ajax/libs/zepto/1.0/zepto.min.js"></script> | |
<script src="//cdn.rawgit.com/enjikaka/WaveformGenerator.js/master/dist/WaveformGenerator2.min.js"></script> | |
<script src="//cdn.rawgit.com/aadsm/JavaScript-ID3-Reader/master/dist/id3-minimized.js"></script> | |
<script src="https://cdn.rawgit.com/taylorhakes/promise-polyfill/master/Promise.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
margin:0; | |
width:100%; | |
height:100%; | |
overflow:hidden; | |
font-family: 'Roboto', sans-serif; | |
} | |
.player { | |
width:100%; | |
height:100%; | |
overflow:hidden; | |
#file-open { | |
display:none; | |
} | |
} | |
.backdrop { | |
width:110%; | |
height:110%; | |
top:-5%; | |
left:-5%; | |
position:absolute; | |
z-index:-99; | |
background-color:#000; | |
img { | |
width:100%; | |
height:100%; | |
display:block; | |
filter:blur(15px); | |
opacity:0.6; | |
} | |
} | |
.main-header { | |
width:100%; | |
display:flex; | |
background-color:rgba(0,0,0,0.2); | |
.left, .right, .center { | |
flex:1; | |
display:flex; | |
padding:1rem; | |
justify-content:flex-start; | |
button { | |
display:block; | |
background:none; | |
border:none; | |
font-size:12pt; | |
outline:none; | |
color:white; | |
} | |
} | |
.right { | |
text-align:right; | |
justify-content:flex-end; | |
} | |
.center { | |
justify-content:center; | |
} | |
/*.play-icon { | |
cursor: pointer; | |
user-select: none; | |
width:12pt; | |
height:12pt; | |
clip-path: polygon(0% 0%, 100% 50%, 0% 100%); | |
transition: all 500ms ease; | |
display:flex; | |
flex-direction:column; | |
div { | |
background-color: #fff; | |
display: block; | |
flex:1; | |
transition: all 500ms ease; | |
} | |
&.pause { | |
clip-path:none; | |
transform: rotate(90deg); | |
div.first { | |
margin-bottom: 20%; | |
} | |
} | |
}*/ | |
.play-icon { | |
$size: 12pt; | |
width:$size; | |
height:$size; | |
overflow:hidden; | |
display:flex; | |
position:relative; | |
clip-path:polygon(0% 0%, 100% 50%, 100% 50%, 0% 100%); | |
user-select:none; | |
appearance:none; | |
cursor:pointer; | |
&:active { | |
&:before, &:after { | |
transition: none; | |
} | |
} | |
&:before, &:after { | |
background-color:rgba(255,255,255,1); | |
display:block; | |
content:''; | |
height:100%; | |
width:50%; | |
} | |
&:after { | |
margin-left:0%; | |
} | |
&, &:after { | |
transition:all 250ms ease; | |
} | |
&.pause { | |
clip-path:polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); | |
&:after { | |
margin-left:12.5%; | |
} | |
} | |
} | |
} | |
main { | |
display:flex; | |
flex-direction:column; | |
align-items:center; | |
justify-content:center; | |
.song-info { | |
margin:2rem 0; | |
display:flex; | |
flex-direction:column; | |
align-items:center; | |
justify-content:center; | |
color:white; | |
text-shadow:1px 1px 0 rgba(0,0,0,0.6); | |
text-align:center; | |
span { | |
display:block; | |
} | |
.song-title { | |
font-size:20pt; | |
} | |
.song-artist { | |
font-size:14pt; | |
margin-top:0.3rem; | |
} | |
} | |
.cover-art { | |
margin: 2rem auto; | |
width: 256px; | |
height: 256px; | |
position:relative; | |
.music-visuals { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
width: 100%; | |
height: 50px; | |
z-index: 99; | |
} | |
img { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
z-index: 90; | |
display:block; | |
} | |
} | |
} | |
.controls { | |
position: relative; | |
.waveform-wrap { | |
width:100%; | |
height: 50px; | |
.background-waveform, .foreground-waveform { | |
position:absolute; | |
width:100%; | |
height:100%; | |
top:0; | |
left:0; | |
z-index:89; | |
overflow:hidden; | |
svg { | |
width:100vw; | |
height:50px; | |
} | |
} | |
.foreground-waveform { | |
width: 50%; | |
z-index:99; | |
} | |
} | |
} | |
@keyframes materialResponse { | |
0% { | |
width: 0; | |
height: 0; | |
margin: 0; | |
background: rgba(255,255,255,0.1); | |
} | |
100% { | |
width: 250%; | |
height: 250%; | |
margin: -125%; | |
background: rgba(255,255,255,0.4); | |
} | |
} | |
@media (max-width:450px) { | |
main .cover-art { | |
img { | |
margin:0 auto; | |
max-width:100%; | |
} | |
} | |
main .song-info { | |
margin:1.5rem 0; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" /> | |
<link href="http://fonts.googleapis.com/css?family=Roboto:400,300" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment