random color setting switch, styling

This commit is contained in:
Egor Philippov 2015-09-30 15:28:28 -07:00
parent 0efdc9b234
commit 4d134259a6
6 changed files with 161 additions and 125 deletions

View file

@ -4,21 +4,16 @@ Music awesomeness for hue lights.
# TODO
## FEATURES
- finish beat detection light effects
- save beat detection settings per song
- change light colors
- app intro with intro.js
- music visualizations with three.js
- listen through mic or integrate with spotify/soundcloud/youtube
## BUGS
- can't create groups anymore
- BUGS BUGS BUGS
## POSSIBLE FEATURES
- clear localstorage
- help, contact, about, youtube video ???
- beat settings by interval
- integration with youtube, soundcloud, spotify ???
- auto beat detection mode
- lights on/off switch

View file

@ -15,16 +15,9 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
actions: {
slideTogglePlayerBottom: function(){
var playerBottomDisplayed = this.get('playerBottomDisplayed');
this.changePlayerControl('playerBottomDisplayed', !playerBottomDisplayed);
if(!playerBottomDisplayed){
Em.$('#playerBottom').slideDown();
} else {
Em.$('#playerBottom').slideUp();
}
this.changePlayerControl('playerBottomDisplayed', !this.get('playerBottomDisplayed'));
},
saveSongPreference: function() {
saveSongSettings: function() {
},
goToSong: function(index){
var dancer = this.get('dancer'), audio = new Audio();
@ -155,7 +148,9 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
transitionTimeChanged: function(value) {
this.changePlayerControl('transitionTime', value);
},
playerBottomDisplayedChanged: function(value) {},
playerBottomDisplayedChanged: function(value) {
this.changePlayerControl('playerBottomDisplayed', value);
},
decayChanged: function(value){
this.changePlayerControl('decay', value, true);
},
@ -174,6 +169,9 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
sequentialTransitionChanged: function(value){
this.set('sequentialTransition', value);
},
onBeatBriOnlyChanged: function(value){
this.set('onBeatBriOnly', value);
},
clickSpeaker: function(){
this.simulateKick(1);
},
@ -266,11 +264,18 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
simulateKick: function(mag) {
var activeLights = this.get('activeLights'),
transitionTime = this.get('transitionTime') * 10,
transitionBriOffFactor = 5,
onBeatBriOnly = this.get('onBeatBriOnly'),
self = this,
brightnessChange = function (light, brightness) {
color = null,
stimulateLight = function (light, brightness, hue) {
var options = {'bri': brightness, 'transitiontime': transitionTime};
if(!Em.isNone(hue)) {
options.hue = hue;
}
Em.$.ajax(self.get('apiURL') + '/lights/' + light + '/state', {
data: JSON.stringify({'bri': brightness, 'transitiontime': transitionTime}),
data: JSON.stringify(options),
contentType: 'application/json',
type: 'PUT'
});
@ -288,8 +293,12 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
light = Math.floor(Math.random() * activeLights.length) + 1;
}
brightnessChange(light, 254);
setTimeout(brightnessChange, transitionTime + 50, light, 1);
if(!onBeatBriOnly) {
color = Math.floor(Math.random() * 65535);
}
stimulateLight(light, 254, color);
setTimeout(stimulateLight, transitionTime + 50, light, 1);
this.set('paused', true);
@ -306,6 +315,7 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
var beatHistory = self.get('beatHistory'),
maxSize = self.get('maxBeatHistorySize');
beatHistory.unshiftObjects('Beat intesity of <b>' + mag.toFixed(3) + '</b> at <b>' + self.get('timeElapsedTxt') + '</b>');
if(beatHistory.length > maxSize){
beatHistory.popObject();
}
@ -342,7 +352,7 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
kick: kick
});
['volume', 'shuffle', 'repeat', 'volumeMuted', 'threshold', 'decay', 'frequency', 'speakerViewed', 'transitionTime', 'sequentialTransition', 'playerBottomDisplayed'].forEach(function (item) {
['volume', 'shuffle', 'repeat', 'volumeMuted', 'threshold', 'decay', 'frequency', 'speakerViewed', 'transitionTime', 'sequentialTransition', 'playerBottomDisplayed', 'onBeatBriOnly'].forEach(function (item) {
if (localStorage.getItem('huegasm.' + item)) {
var itemVal = localStorage.getItem('huegasm.' + item);
if (item === 'repeat' || item === 'volume' || item === 'decay' || item === 'threshold' || item === 'transitionTime') {
@ -371,10 +381,6 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
event.preventDefault();
});
if(!this.get('playerBottomDisplayed')){
Em.$('#playerBottom').hide();
}
// control the volume by scrolling up/down
Em.$('#playerArea').on('mousewheel', function(event) {
if(self.get('playQueueNotEmpty')) {

View file

@ -121,12 +121,21 @@ export default Em.Mixin.create({
sequentialTransition: true,
sequentialTransitionLabel: function() {
if(this.get('sequentialTransition')){
return 'Sequential';
return 'Sequential Transition';
} else {
return 'Random';
return 'Random Transition';
}
}.property('sequentialTransition'),
onBeatBriOnly: true,
onBeatBriOnlyLabel: function() {
if(this.get('onBeatBriOnly')){
return 'Brightness';
} else {
return 'Brightness & Color';
}
}.property('onBeatBriOnly'),
changePlayerControl: function(name, value, isOption){
if(isOption){
var options = {};
@ -203,9 +212,9 @@ export default Em.Mixin.create({
this.get('beatHistory').clear();
}.observes('speakerViewed'),
onSequentialTransitionChange: function(){
localStorage.setItem('huegasm.sequentialTransition', this.get('sequentialTransition'));
}.observes('sequentialTransition'),
onOptionChange: function(self, option){
localStorage.setItem('huegasm.' + option, this.get(option));
}.observes('sequentialTransition', 'onBeatBriOnly'),
onRepeatChange: function () {
var tooltipTxt = 'Repeat all', type = 'repeat';
@ -282,7 +291,7 @@ export default Em.Mixin.create({
},
beatDetectionArrowIcon: function(){
if(this.get('playerBottomDisplayed')){
if(!this.get('playerBottomDisplayed')){
return 'arrow-drop-down';
} else {
return 'arrow-drop-up';

View file

@ -8,6 +8,7 @@ $playerHeight: 400px;
$playListBackgroundColor: #1E1E1E;
$playerDefaultIconColor: #BBBBBB;
$footerHeight: 40px;
$playerBottomBackground: #5D5D5D;
// BRIDGE FINDER
html {
@ -17,7 +18,7 @@ html {
body {
font-family: 'Slabo 27px', serif;
margin-bottom: $footerHeight;
margin-bottom: $footerHeight + 20px;
position: static;
}
@ -398,10 +399,9 @@ md-toolbar {
}
#slideToggle {
position: absolute;
z-index: 100;
left: 45%;
color: white;
background-color: $playerBottomBackground;
padding: 5px;
}
md-switch.md-default-theme.md-checked .md-bar {
@ -662,18 +662,23 @@ md-switch.md-default-theme.md-checked .md-thumb {
margin-bottom: 15px;
}
#beatOptionGroup {
.beatOption {
text-align: center;
.optionDescription {
font-size: 13px;
}
#beatOptionButtonGroup {
margin: 20px 0;
}
.beatOption {
text-align: center;
md-switch {
margin: 0;
}
.optionDescription {
font-size: 13px;
}
}
#playerBottom {
color: white;
background-color: #5D5D5D;
background-color: $playerBottomBackground;
width: 100%;
}
@ -748,10 +753,10 @@ md-switch.md-default-theme.md-checked .md-thumb {
#beatHistory {
color: black;
height: 250px;
height: 300px;
background-color: white;
border-radius: 10px;
width: 80%;
width: 90%;
margin: 20px auto;
overflow: auto;
padding: 10px;

View file

@ -1,21 +1,26 @@
<div class="row">
<div id="playerArea" class="col-sm-8 col-xs-12" {{action "playerAreaPlay"}}>
<div id="playerArea" class="col-sm-8 col-xs-12" {{action "playerAreaPlay"}}>
<div id="playNotification" class="material-icons {{if fadeOutNotification "fadeOut"}} {{if playing "play-arrow" "pause"}}"></div>
<div id="playerControls">
{{range-slider start=seekPosition min=0 max=100 id="seekSlider" slide="seekChanged"}}
<div id="playNotification"
class="material-icons {{if fadeOutNotification "fadeOut"}} {{if playing "play-arrow" "pause"}}"></div>
<div id="playerControls">
{{range-slider start=seekPosition min=0 max=100 id="seekSlider" slide="seekChanged"}}
{{#if playQueueMultiple}}
<span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" id="prevTooltip" data-title={{prevTooltipTxt}} {{action "previous"}}>{{paper-icon icon="skip-previous" class="playerControllIcon"}}</span><!--
{{#if playQueueMultiple}}
<span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" id="prevTooltip"
data-title={{prevTooltipTxt}} {{action "previous"}}>{{paper-icon icon="skip-previous" class="playerControllIcon"}}</span><!--
-->{{/if}}<!--
--><span data-toggle="tooltip" data-placement="top" id="playingTooltip" class="bootstrapTooltip" data-title={{playingTooltipTxt}} {{action "play"}}>{{paper-icon icon=playingIcon class="playerControllIcon"}}</span><!--
--><span data-toggle="tooltip" data-placement="top" id="playingTooltip" class="bootstrapTooltip"
data-title={{playingTooltipTxt}} {{action "play"}}>{{paper-icon icon=playingIcon class="playerControllIcon"}}</span><!--
-->{{#if playQueueMultiple}}<!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" data-title="Next" {{action "next"}}>{{paper-icon icon="skip-next" action="" class="playerControllIcon"}}</span><!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip"
data-title="Next" {{action "next"}}>{{paper-icon icon="skip-next" action="" class="playerControllIcon"}}</span><!--
-->{{/if}}<!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" id="volumeMutedTooltip" data-title={{volumeMutedTooltipTxt}} {{action "volumeMutedChanged"}}>{{paper-icon icon=volumeClass class="playerControllIcon volumeButton"}}</span><!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" id="volumeMutedTooltip"
data-title={{volumeMutedTooltipTxt}} {{action "volumeMutedChanged"}}>{{paper-icon icon=volumeClass class="playerControllIcon volumeButton"}}</span><!--
-->{{range-slider start=volume min=0 max=100 slide="volumeChanged" id="volumeBar"}}
<div id="playerTimeControls">{{timeElapsedTxt}} / {{timeTotalTxt}}</div>
<div id="playerTimeControls">{{timeElapsedTxt}} / {{timeTotalTxt}}</div>
<span class="pull-right">
<span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip"
@ -25,13 +30,13 @@
data-title="Full screen" {{action "fullscreen"}}>{{paper-icon icon="fullscreen" class="playerControllIcon"}}
</span>
</span>
</div>
</div>
</div>
<div id="playlist" class="col-sm-4 col-xs-12">
<input id="fileInput" type="file" accept="audio/*" multiple="true" />
<div id="playlist" class="col-sm-4 col-xs-12">
<input id="fileInput" type="file" accept="audio/*" multiple="true"/>
<div id="playListControls">
<div id="playListControls">
<span data-toggle="tooltip" data-placement="bottom auto" class="bootstrapTooltip" id="shuffleTooltip"
data-title={{shuffleTooltipTxt}} {{action "shuffleChanged"}}>{{paper-icon icon="shuffle" class=shuffleClass}}</span>
@ -40,88 +45,103 @@
<span data-toggle="tooltip" data-placement="bottom" data-title="Add new music"
class="pull-right bootstrapTooltip" {{action "addAudio"}}>{{paper-icon icon="add" class="playerControllIcon" }}</span>
</div>
<div id="playListArea" class={{playListAreaClass}} {{action "playListAreaAddAudio"}} {{action "playListAreaDragOver" on="dragOver"}} {{action "playListAreaDragLeave" on="dragLeave"}} {{action "dropFiles" on="drop"}}>
{{#if (or playQueueEmpty dragging)}}
<div id="dragHere">
{{#if dragging}}
Drag your music files here
{{else}}
Add your music files here
{{/if}}
</div>
{{paper-icon icon="library-music"}}
{{/if}}
{{#each playQueue as |item index|}}
<div class="playlistItem cursorPointer {{if (eq index playQueuePointer) "active"}} {{if dragging "hidden"}}" {{action "goToSong" index bubbles=false}}>
{{#if item.title}}
{{item.title}}
<div class="songArtist">{{item.artist}}</div>
{{else}}
{{item.filename}}
{{/if}}
<div data-toggle="tooltip" data-placement="bottom auto" data-title="Remove from playlist" class="audioRemoveButton cursorPointer bootstrapTooltip" {{action "removeAudio" index bubbles=false}}>{{paper-icon icon="close"}}</div></div>
{{/each}}
</div>
</div>
</div>
<div id="slideToggle" class="text-center cursorPointer" {{action "slideTogglePlayerBottom"}}>
{{paper-icon icon=beatDetectionArrowIcon}} Beat Detection Settings {{paper-icon icon=beatDetectionArrowIcon}}
</div>
<div id="playerBottom" class="row">
<div id="beatArea" class="col-sm-8 col-xs-12">
<div id="vertDivider" class="hidden-xs"></div>
<div class="row">
Light Selection {{#paper-switch checked=sequentialTransition}} {{sequentialTransitionLabel}} {{/paper-switch}}
</div>
<div id="beatOptionGroup" class="row">
<div class="beatOption col-xs-3">
<div class="text-center">{{threshold}}</div>
{{range-slider start=threshold orientation="vertical" step=beatOptions.threshold.step range=beatOptions.threshold.range slide="thresholdChanged" pips=beatOptions.threshold.pips}}
<span class="optionDescription">Max. Intensity</span>
</div>
<div id="playListArea"
class={{playListAreaClass}} {{action "playListAreaAddAudio"}} {{action "playListAreaDragOver" on="dragOver"}} {{action "playListAreaDragLeave" on="dragLeave"}} {{action "dropFiles" on="drop"}}>
{{#if (or playQueueEmpty dragging)}}
<div id="dragHere">
{{#if dragging}}
Drag your music files here
{{else}}
Add your music files here
{{/if}}
</div>
{{paper-icon icon="library-music"}}
{{/if}}
<div class="beatOption col-xs-3">
<div class="text-center">{{decay}} sec</div>
{{range-slider start=decay orientation="vertical" step=beatOptions.decay.step range=beatOptions.decay.range slide="decayChanged" pips=beatOptions.decay.pips}}
<span class="optionDescription">Decay Rate</span>
</div>
{{#each playQueue as |item index|}}
<div
class="playlistItem cursorPointer {{if (eq index playQueuePointer) "active"}} {{if dragging "hidden"}}" {{action "goToSong" index bubbles=false}}>
{{#if item.title}}
{{item.title}}
<div class="songArtist">{{item.artist}}</div>
{{else}}
{{item.filename}}
{{/if}}
<div data-toggle="tooltip" data-placement="bottom auto" data-title="Remove from playlist"
class="audioRemoveButton cursorPointer bootstrapTooltip" {{action "removeAudio" index bubbles=false}}>{{paper-icon icon="close"}}</div>
</div>
{{/each}}
</div>
</div>
</div>
<div class="beatOption col-xs-3">
<div class="text-center">[{{#each frequency as |item index|}}{{item}}{{#unless index}} ,{{/unless}}{{/each}}]</div>
{{range-slider start=frequency orientation="vertical" step=beatOptions.frequency.step range=beatOptions.frequency.range connect=true slide="frequencyChanged" pips=beatOptions.frequency.pips}}
<span class="optionDescription">Frequency Range</span>
</div>
<div class="text-center cursorPointer row" {{action "slideTogglePlayerBottom"}}>
<div id="slideToggle" class="col-xs-12">
{{paper-icon icon=beatDetectionArrowIcon}} Beat Detection Settings {{paper-icon icon=beatDetectionArrowIcon}}
</div>
</div>
<div class="beatOption col-xs-3">
<div class="text-center">{{transitionTime}} sec</div>
{{#if playerBottomDisplayed}}
<div id="playerBottom" class="row">
<div id="beatArea" class="col-sm-8 col-xs-12">
<div id="vertDivider" class="hidden-xs"></div>
<div class="row">
<div class="beatOption col-xs-3">
<div class="text-center">{{threshold}}</div>
{{range-slider start=threshold orientation="vertical" step=beatOptions.threshold.step range=beatOptions.threshold.range slide="thresholdChanged" pips=beatOptions.threshold.pips}}
<span data-toggle="tooltip" data-placement="bottom auto" data-title="Maximum intensity of the sound that may be registered as a beat" class="optionDescription bootstrapTooltip">Max. Intensity</span>
</div>
<div class="beatOption col-xs-3">
<div class="text-center">{{decay}}</div>
{{range-slider start=decay orientation="vertical" step=beatOptions.decay.step range=beatOptions.decay.range slide="decayChanged" pips=beatOptions.decay.pips}}
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The rate at which the previously registered beat's intensity is reduced to find the next beat" class="optionDescription bootstrapTooltip">Decay Rate</span>
</div>
<div class="beatOption col-xs-3">
<div class="text-center">[{{#each frequency as |item index|}}{{item}}{{#unless index}} ,{{/unless}}{{/each}}
]
</div>
{{range-slider start=frequency orientation="vertical" step=beatOptions.frequency.step range=beatOptions.frequency.range connect=true slide="frequencyChanged" pips=beatOptions.frequency.pips}}
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The frequency range of sound to listen on for the beat" class="optionDescription bootstrapTooltip">Frequency Range</span>
</div>
<div class="beatOption col-xs-3">
<div class="text-center">{{transitionTime}} sec</div>
{{range-slider start=transitionTime orientation="vertical" step=beatOptions.transitionTime.step range=beatOptions.transitionTime.range slide="transitionTimeChanged" pips=beatOptions.transitionTime.pips}}
<span class="optionDescription">Transition Time</span>
<span data-toggle="tooltip" data-placement="bottom auto" data-title="Transition time to change the lights on, on beat" class="optionDescription bootstrapTooltip">Transition Time</span>
</div>
</div>
<div id="beatOptionButtonGroup" class="row">
<div class="beatOption col-xs-6">
{{#paper-switch checked=sequentialTransition disabled=trial}}<span data-toggle="tooltip" data-placement="bottom auto" data-title="The order in which the active lights are transitioned to on beat" class="optionDescription bootstrapTooltip">{{sequentialTransitionLabel}}</span>{{/paper-switch}}
</div>
<div class="beatOption col-xs-6">
{{#paper-switch checked=onBeatBriOnly disabled=trial}}<span data-toggle="tooltip" data-placement="bottom auto" data-title="The properties of the lights to change on beat" class="optionDescription bootstrapTooltip"> {{onBeatBriOnlyLabel}}</span>{{/paper-switch}}
</div>
</div>
</div>
<div id="playerButtonGroup" class="row">
{{#paper-button raised=true warn=true action="defaultControls"}}Default{{/paper-button}}
{{#paper-button raised=true action="saveSongPreference"}}Save Song Preference{{/paper-button}}
{{#paper-button raised=true action="saveSongSettings"}}Save Song Settings{{/paper-button}}
</div>
</div>
<div id="beatContainer" class="col-sm-4 col-xs-12">
{{#if speakerViewed}}
<div id="beatSpeaker">
<img src="assets/images/speaker-outer.png" />
<div id="beatSpeakerCenter">
<img src="assets/images/speaker-inner.png" class="cursorPointer" {{action "clickSpeaker"}} />
</div>
<img src="assets/images/speaker-outer.png"/>
<div id="beatSpeakerCenter">
<img src="assets/images/speaker-inner.png" class="cursorPointer" {{action "clickSpeaker"}} />
</div>
</div>
{{else}}
<div id ="beatHistory">
<div id="beatHistory">
{{#each beatHistory as |item|}}
<p>{{{item}}}</p>
{{/each}}
@ -130,4 +150,5 @@
{{#paper-switch checked=speakerViewed}} {{speakerLabel}} {{/paper-switch}}
</div>
</div>
</div>
{{/if}}

View file

@ -1 +1 @@
<p class="text-muted">Made with ¯\_(ツ)_/¯ by <a href="//egorphilippov.me">egorphilippov.me</a> © 2015 Huegasm</p>
<p class="text-muted">Made by <a href="//egorphilippov.me">egorphilippov.me</a> © 2015 Huegasm</p>