Browse Source

Improve displaying sequencer controls

fillotassi 5 years ago
parent
commit
d6264266ae
3 changed files with 158 additions and 47 deletions
  1. 109 11
      components/sequencer.vue
  2. 2 0
      package.json
  3. 47 36
      pages/index.vue

+ 109 - 11
components/sequencer.vue

@@ -1,17 +1,32 @@
 <template>
   <section class="sequencer" v-on:mouseover="displayControls()" v-on:mouseleave="hideControls()" >
+    <!--<span class="sequence-controls-wrapper">-->
+    <div class="options-wrapper">
+      <div class="control-bar">
+        <div class="sequence-options">
+          <div class="option-icon" id="icon-slots"></div>
+          <div class="option-icon" id="icon-euclid"></div>
+          <div class="option-icon" id="icon-sample"></div>
+          <div class="option-icon" id="icon-delete"></div>
+        </div>
+        <div class="sequence-bar">
+          <range-slider class="slider" min="1" step="1" v-model="slotSlider" v-on:input="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
+          <input id="pulseSlider"/>
+          <range-slider class="slider"  min="1" :max="slotSlider" step="1" v-model="pulseSlider" v-on:input  ="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
+          <input id="pulseSlider" value="3" />
+        </div>
+      </div>
+    </div>
     <div class="sequencerLine">
         <div class="slot" v-for="(slot, slotid) in euclideanList" :key="slotid">
           <beat :id="'slot'+slotid" v-if="slot === 1"></beat>
           <div v-else class="emptySlot"></div>
         </div>
     </div>
+  <!--<</span>-->
     <div>
-      <div class="control-menu" :class="[{'displayControls': controlIsDisplayed}]">
-        <range-slider class="slider" min="1" step="1" v-model="slotSlider" v-on:input="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
-        <input id="pulseSlider"/>
-        <range-slider class="slider"  min="1" :max="slotSlider" step="1" v-model="pulseSlider" v-on:input  ="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
-        <input id="pulseSlider" value="3" />
+      <!--<div class="control-menu" style="margin-top:5em;" :class="[{'displayControls': controlIsDisplayed}]">-->
+      <div class="control-menu" style="margin-top:5em;">
       </div>
     </div>
   </section>
@@ -46,7 +61,11 @@
         },
         hideControls: function (){
           this.controlIsDisplayed = false;
-        },
+        }
+        /*,
+        barOpacity: function (){
+          this.setOpacity = true;
+        }*/,
         bjorklund: function (slots, pulses) {
 
       var pattern = [],
@@ -127,18 +146,97 @@
   display: none;
 }
 
-.slider{
-  width:30%;
-}
-
 .displayControls{
   display:flex !important;
 }
 
+.sequence-options{
+  width:auto;
+  height: 3em;
+  z-index: 2;
+  background-color: red;
+  display: none;
+}
+
+.option-icon{
+  width:3em;
+  height: 3em;
+  background:white;
+}
+
+#icon-slots{
+  background-image: url("~/assets/img/squares.png");
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+#icon-euclid{
+  background-image: url("~/assets/img/pixel.png");
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+#icon-sample{
+  background-image: url("~/assets/img/bell.png");
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+#icon-delete{
+  background-image: url("~/assets/img/close.png");
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+.options-wrapper{
+  background-color: darkgoldenrod;
+  width:3em;
+  height: 3em;
+  display:flex;
+  background-image: url("~/assets/img/squares.png");
+  background-repeat: no-repeat;
+  background-position: center;
+  z-index: 2;
+}
+.options-wrapper:hover > .control-bar > .sequence-options{
+  display:block;
+  position: absolute;
+  margin-left:3em;
+  display: flex;
+  overflow-x: auto;
+}
+
+.sequence-bar{
+  display:none;
+}
+
+.options-wrapper:hover > .control-bar > .sequence-options + .sequence-bar{
+  display: block;
+  flex:1 1 100%;
+  background: blue;
+  overflow-x: auto;
+  position: absolute;
+  width:100%;
+  margin-left:15em;
+  height:3em;
+}
+
+.options-menu{
+  width:5em;
+  height: 3em;
+  z-index: 1;
+  background-color: dimgrey;
+  display: none;
+}
+
+.sequencer{
+  display:flex;
+}
+
 .sequencerLine{
     display:flex;
     height:3em;
-    width:auto;
+    width:100%;
     background-color:firebrick;
 }
 

+ 2 - 0
package.json

@@ -23,6 +23,8 @@
     "eslint-friendly-formatter": "^3.0.0",
     "eslint-loader": "^1.7.1",
     "eslint-plugin-vue": "^4.0.0",
+    "node-sass": "^4.9.3",
+    "sass-loader": "^7.1.0",
     "vue-input-number": "^0.1.5"
   }
 }

+ 47 - 36
pages/index.vue

@@ -1,33 +1,19 @@
 <template>
   <div id="app">
-  <h2 id="titolone" class="subtitle" style="background:beige;position:absolute;bottom:0">
-    Second attempt at building a web interface for ESP8266
-  </h2>
-  <div style="margin-top:1em;margin-bottom:1em;display:flex;width:100%;height:3em;background:#3333333;align-items:center;justify-content:center">
-    <div>
-      <div class="icon-button" style="flex:1 1 auto" v-on:click="addLine()">
-        <img style="margin:auto;" src="~/assets/img/add.png">
+  <div id="app-wrapper">
+      <div id="gadgety-view">
+        <div id="left-bar">
+        <div class="sequencer-wrapper" v-for="line in lines" :key='line.id'>
+          <sequencer class="jsonSequencer" :id='line.id' :line='line'></sequencer>
+        </div>
+        <div class="icon-button" v-on:click="addLine()"></div>
       </div>
+        <div class="icon-wrapper">
+          <input type="number" style="width:5em;height:2em;background:red;border:none;color:white;" v-model="bpm" >
+          <input type="submit" value="Send!" style="width:5em;height:2em;background:red;border:none;color:white;" v-on:click="getSequencerData()">
+        </div>
     </div>
   </div>
-  <div v-for="line in lines" :key='line.id'>
-    <sequencer class="jsonSequencer" :id='line.id' :line='line'></sequencer>
-  </div>
-    <div class="icon-wrapper">
-      <div class="icon-button">
-        <img style="margin:auto;" src="~/assets/img/barrier.png">
-      </div>
-      <div class="icon-button">
-        <img style="margin:auto;" src="~/assets/img/pixel.png">
-      </div>
-      <div class="icon-button">
-        <img style="margin:auto;" src="~/assets/img/squares.png">
-      </div>
-      <div class="icon-button">
-        <img style="margin:auto;" src="~/assets/img/bell.png">
-      </div>
-      <input type="submit" value="Send!" style="width:5em;height:2em;background:red;border:none;color:white;" v-on:click="getSequencerData()">
-    </div>
   </div>
 </template>
 
@@ -40,9 +26,10 @@ import moduleData from '~/assets/js/moduleData.json'
 export default {
   data() {
     return {
-      lines: []
+      lines: [],
       // https://stackoverflow.com/questions/44869287/set-object-in-data-from-a-method-in-vue-js#44869373
       // creata object in data vue
+      bpm:120
     }
   },
   components: {
@@ -62,7 +49,7 @@ export default {
     },
     getSequencerData: function(){
       var modelEsp = {
-        'millis_per_slot': 500, // bpm = 60000 / millis_per_slot
+        'millis_per_slot': Math.floor(60000 / this.bpm), // bpm = 60000 / millis_per_slot
         'lines': this.lines.map(function(line) {
           return line.euclideanList.reduce(function(acc, x) { return acc + x.toString(); }, '');
         })
@@ -74,27 +61,51 @@ export default {
       xhr.onreadystatechange = function () {
         if(xhr.readyState === 4 && xhr.status === 200) {
           //self.commits = JSON.parse(xhr.responseText);
-          console.log("Recv", xhr.responseText);
+          console.log("Sent", xhr.responseText);
         }
       };
 
       xhr.setRequestHeader('Content-Type', 'application/json');
+      console.log("Sending", modelEsp);
       xhr.send(JSON.stringify(modelEsp));
     }
   }
 }
 </script>
+
 <style>
+#app{
+  height:100vh;
+  background-color: cornflowerblue;
+}
+
+#app-wrapper{
+  height: 100%;
+  background: brown;
+  display: flex;
+}
+
+#left-bar{
+  flex:1 1 3em;
+  background-color: crimson;
+  display: flex;
+  flex-wrap: wrap;
+}
+
 .icon-button{
-  display:flex;
-  background-color:red;
-  width:3em;
-  height:3em;
-  border-radius:3em;
-  margin:0.2em;
+   width: 3em;
+   height: 3em;
+   background: white;
+   background-image: url("~/assets/img/add.png");
+   background-repeat: no-repeat;
+   background-position: center;
 }
 
-.icon-wrapper{
-  display:flex;
+.sequencer-wrapper{
+  flex:1 1 100%;
+}
+#gadgety-view{
+  flex: 1 1 auto;
+  top:0;
 }
 </style>