Skip to content

Instantly share code, notes, and snippets.

@Archangel212
Last active August 5, 2017 15:17
Show Gist options
  • Save Archangel212/a903fd41a413e1da175b0fde8241043e to your computer and use it in GitHub Desktop.
Save Archangel212/a903fd41a413e1da175b0fde8241043e to your computer and use it in GitHub Desktop.
Using CSS Vars for Themes
<div class="hidden">
<input id=audiofile type=file>
<div id="audio_box"></div>
</div>
<h2 class="title">Using CSS Vars for Themes</h2>
<div class="demo">
<div id="player">
<div class="visor">
<div class="time">
<span class="current">0:00</span>
<span class="duration">0:00</span>
</div>
<div class="info">
<div class="track">Artist - Song Title</div>
<div class="status">
<span></span>
<span>128 KBPS</span>
<span>44 KHZ</span>
<span><i class="zmdi zmdi-surround-sound"></i></span>
</div>
</div>
</div>
<div class="controls">
<button class="open-button" alt="open">
<i class="zmdi zmdi-eject"></i>
</button>
<button class="play-button" alt="play">
<i class="zmdi zmdi-play"></i>
</button>
<button class="pause-button" alt="pause">
<i class="zmdi zmdi-pause"></i>
</button>
<button class="repeat-button" alt="repeat" title="repeat">
<i class="zmdi zmdi-repeat"></i>
</button>
</div>
<div class="analyser">
<canvas id="analyser_render"></canvas>
</div>
</div>
<div class="themes">
<div class="radio">
<input id="radio-1" name="radio" type="radio" value="0" checked>
<label for="radio-1" class="radio-label">Night</label>
</div>
<div class="radio">
<input id="radio-2" name="radio" type="radio" value="1">
<label for="radio-2" class="radio-label">Fire</label>
</div>
<div class="radio">
<input id="radio-3" name="radio" type="radio" value="2">
<label for="radio-3" class="radio-label">Classic</label>
</div>
</div>
</div>
<footer>
<h2>About this Pen</h2>
<p>To test the player just click on the open (<i class="zmdi zmdi-eject"></i>) button, select your favorite audio file and see how it works.</p>
<p>This is one of the new features comming in the next update of Flamapop, soon you will be able to select from three themes we made for you. </p>
<p>Flamapop is a Google Chrome extension that allows to control the playback of the current Youtube video from any tab in your browser.</p>
<p class="right">
<a href="https://chrome.google.com/webstore/detail/flamapop/knnlmpnmodboangkbfcghejobbbokadl" target="_blank">
<img src="https://lh3.googleusercontent.com/IuTJuEcuFZ0s8CKZ4Ie6PLngqB4aq5e8TsUz0kPgKjLZ6siNYIpmEoI4S_zvxYJiVl_3ZQTxSg=w26-h26-e365" alt="flamapop-logo" />
<span>See Flamapop at Chrome Store</span>
</a>
</p>
</footer>
var audio = null,
analyser = null,
audioContext = null,
sourceNode = null,
stream = null;
var barsColor = '#00CCFF';
var audioInput = document.getElementById('audiofile');
var timeRender = document.querySelector('.time .current');
var trackRender = document.querySelector('.track');
var canvas, ctx;
// choose file
audioInput.addEventListener('change', function(event) {
stream = URL.createObjectURL(event.target.files[0]);
if(audio === null) {
audio = new Audio();
audio.src = stream;
audio.controls = true;
audio.autoplay = true;
}
else {
audio.removeAttribute('src');
audio.load();
audio.setAttribute('src', stream);
audio.load();
setTimeout(() => audio.play(), 400);
}
trackRender.textContent = event.target.files[0].name;
barsColor = getComputedColor('.analyser');
if(audioContext === null)
setup();
});
function setup() {
audio.addEventListener('canplay', function () {
document.body.className+='loaded';
document.getElementById('audio_box').appendChild(audio);
var AudioContext = window.AudioContext || window.webkitAudioContext;
audioContext = new AudioContext();
analyser = (analyser || audioContext.createAnalyser());
sourceNode = audioContext.createMediaElementSource(audio);
sourceNode.connect(analyser);
sourceNode.connect(audioContext.destination);
canvas = document.getElementById('analyser_render');
ctx = canvas.getContext('2d');
document.querySelector('.status').classList.add('play');
document.querySelector('.duration').textContent = formatTime(audio.duration);
audio.play();
update();
});
}
function update(){
window.webkitRequestAnimationFrame(update);
var fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
ctx.fillStyle = barsColor; // Color of the bars
var bars = 50;
for (var i = 0; i < bars; i++) {
var bar_x = i * 6;
var bar_width = 5;
var bar_height = -(fbc_array[i] / 2);
ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
}
timeRender.textContent = formatTime(audio.currentTime);
}
function formatTime(seconds) {
var minutes = Math.floor(seconds / 60);
minutes = (minutes >= 10) ? minutes : "" + minutes;
var seconds = Math.floor(seconds % 60);
seconds = (seconds >= 10) ? seconds : "0" + seconds;
return minutes + ":" + seconds;
}
function getComputedColor(selector)
{
var element = document.querySelector(selector);
if (element.currentStyle)
return element.currentStyle.backgroundColor;
if (window.getComputedStyle)
{
var elementStyle=window.getComputedStyle(element,"");
if (elementStyle)
return elementStyle.getPropertyValue("color");
}
// Return 0 if both methods failed.
return 0;
}
document.querySelector('.play-button').addEventListener("click", e => {
audio.play();
document.querySelector('.status').classList.add('play');
}, false);
document.querySelector('.pause-button').addEventListener("click", e => {
audio.pause();
document.querySelector('.status').classList.remove('play');
}, false);
document.querySelector('.repeat-button').addEventListener("click", e => {
var btn = e.currentTarget;
if(!audio.loop) {
audio.loop = true;
btn.style.opacity = .5;
}
else {
audio.loop = false;
btn.style.opacity = .9;
}
}, false);
document.querySelector('.open-button').addEventListener("click", e => {
document.querySelector('#audiofile').click();
}, false);
var themes = [
{
bg: '#222',
visor: '#002D3C',
text: '#F5F5F5',
bars: '#00CCFF'
},
{
bg: '#F44336',
visor: '#dadada',
text: '#F5F5F5',
bars: '#6b6b6b'
},
{
bg: '#333',
visor: '#222',
text: '#F5F5F5',
bars: '#F00'
}
]
function setThemeVar(name, value, unit) {
var rootStyles = document.styleSheets[1].cssRules[1].style;
rootStyles.setProperty('--' + name, value + (unit || ''));
}
var radios = document.querySelectorAll('.radio input');
for(var i = 0, max = radios.length; i < max; i++) {
radios[i].onclick = e => {
var index = parseInt(e.currentTarget.value);
var theme = themes[index];
barsColor = theme.bars;
setThemeVar('bg-color', theme.bg);
setThemeVar('visor-color', theme.visor);
setThemeVar('text-color', theme.text);
setThemeVar('bars-color', theme.bars);
}
}
radios[1].click();
@import url(https://fonts.googleapis.com/css?family=Lato|Roboto:100,400);
:root {
--bg-color: #322;
--visor-color: #002D3C;
--text-color: #f5f5f5;
--bars-color: #00CCFF;
--transition-config: background .8s ease;
}
body {
font-family: 'Lato', Helvetica;
padding: 0;
margin: 0;
background-color: #f5f5f5;
display: flex;
flex-direction: column;
}
div#player {
width:500px;
height:170px;
background: #444;
background:var(--bg-color);
padding:15px;
/* margin:50px auto; */
margin-right: 10px;
font-family: 'Roboto', Helvetica;
color: var(--bars-color);
border-radius: 2px;
transition: var(--transition-config);
}
div#player .visor {
width: 100%;
height: 90px;
background: #dadada;
background:var(--visor-color);
transition: var(--transition-config);
}
div#player .visor > div {
display: inline-block;
position: relative;
}
div#player .info {
width: 270px;
padding-left: 20px;
height: 100%;
}
div#player .info > div {
height: 50%;
width: 100%;
display: flex;
align-items: center;
}
div#player .analyser {
position: relative;
width:200px;
height:70px;
background:#dadada;
background:var(--visor-color);
padding: 0 10px 10px;
transition: var(--transition-config);
}
div#player .analyser canvas {
width:100%;
height:100%;
background: #dadada;
background:var(--visor-color);
transition: var(--transition-config);
}
.time {
width: 200px;
position: relative;
left: 10px;
top: -5px;
font-size: 20px;
font-weight: 100;
}
.time .current {
font-size: 64px
}
.time .duration {
opacity:.3;
font-weight: 400
}
.status {
justify-content: space-around;
font-size: 12px;
}
.status span:first-child:before {
content: '\f3a7';
font: normal normal normal 14px/1 'Material-Design-Iconic-Font';
}
.status.play span:first-child:before {
content: '\f3aa';
}
.track { font-size: 14px; }
.controls {
float: right;
width: 260px;
height: 60px;
}
.controls button {
border: none;
background-color: rgba(255,255,255,.0);
color: #FFF;
color: var(--text-color);
border-radius: 50%;
font-size: 32px;
width: 48px;
height: 48px;
margin-right: 0px;
margin-top: 25px;
outline: none;
cursor: pointer;
opacity: .9;
transition: all .4s ease;
}
.controls button:hover {
transform: scale(1.1);
opacity: 1;
}
.open-button {
float: right;
}
.hidden {
display: none;
}
h2.title {
text-align: center;
margin: 45px auto;
color: #444;
}
.demo {
width: 680px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
}
.demo > div {
display: inline-block
}
footer {
margin-top: 60px;
padding: 15px;
background: #444;
background-color: var(--bg-color);
color: #fff;
color: var(--text-color);
transition: all .4s ease;
flex-grow: 2;
}
footer {
h2, p {
max-width: 640px;
margin: 20px auto;
line-height: 1.5;
}
h2 {
opacity: 0.6;
}
a {
color: #444;
text-decoration: none;
background-color: #ddd;
padding: 8px 12px;
border-radius: 2px;
}
img {
vertical-align: text-bottom;
width: 24px;
position: relative;
top: 2px;
}
p.right {
text-align: right;
margin-top: 25px
}
}
/** Radio buttons **/
$color1: #f4f4f4;
$color2: #3197EE;
.radio {
// display: inline-block;
margin: 0.5rem;
input[type="radio"] {
position: absolute;
opacity: 0;
+ .radio-label {
&:before {
content: '';
background: $color1;
border-radius: 100%;
border: 1px solid darken($color1, 25%);
display: inline-block;
width: 1.4em;
height: 1.4em;
position: relative;
top: -0.2em;
margin-right: 1em;
vertical-align: top;
cursor: pointer;
text-align: center;
transition: all 250ms ease;
}
}
&:checked {
+ .radio-label {
&:before {
background-color: $color2;
box-shadow: inset 0 0 0 4px $color1;
}
}
}
&:focus {
+ .radio-label {
&:before {
outline: none;
border-color: $color2;
}
}
}
&:disabled {
+ .radio-label {
&:before {
box-shadow: inset 0 0 0 4px $color1;
border-color: darken($color1, 25%);
background: darken($color1, 25%);
}
}
}
+ .radio-label {
&:empty {
&:before {
margin-right: 0;
}
}
}
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/css/material-design-iconic-font.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment