Improve model view and add BPM

This commit is contained in:
fillotassi 2018-09-09 23:59:01 +02:00
parent 5257102b3d
commit a4b63c8657
14 changed files with 10762 additions and 57 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

10449
assets/img/gadgety-favicon.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 506 KiB

View file

@ -0,0 +1,2 @@
{
}

View file

@ -0,0 +1,44 @@
{
"lines": [
{
"lines_1": [
{
"beats": [
{
"beats_1": [
{
"subdivisions": [
{
"name": "suddivisions_1",
"offset": "12345"
},
{
"name": "suddivisions_2",
"offset": "6789"
}
]
}
]
},
{
"beats_2": [
{
"subdivisions": [
{
"name": "suddivisions_1",
"offset": "12345"
},
{
"name": "suddivisions_2",
"offset": "6789"
}
]
}
]
}
]
}
]
}
]
}

View file

@ -3,12 +3,10 @@
<input v-model="divisioni" type="number" min="1" oninput="validity.valid||(value='');">
<!--- trovare modo per prevenire scrittura di input-->
<div class="division-wrapper">
<div class="beat" v-for="j in nDivisioni" :key='j'>
<div>{{randomColori()}}</div>
<div class="suddivisione" :style="{'background-color': colore }"></div>
<div class="suddivisione-wrapper" v-for="j in nDivisioni" :key='j' :id="'suddivisione'+j" >
<div class="suddivisione-content" :style="{'background-color': colore }" style="max-width:1em"></div>
</div>
</div>
<!-- <beatMenu></beatMenu>-->
</div>
</template>
<script>
@ -16,8 +14,10 @@
name: 'beat',
data() {
return {
nome:'',
colore: 'red',
divisioni: 1
divisioni: 1,
timing: 0
}
},
computed: {
@ -27,27 +27,19 @@
}
},
methods: {
checkDivisioni: function (){
console.log("numero dell'input è" + this.nDivisioni)
},
randomColori: function (){
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
console.log(color);
this.colore = color;
titolo(progressivo){
this.nome = "nomeBeat" + progressivo;
}
}
}
</script>
<style>
.beat{
.suddivisione-wrapper{
flex: 1 1 auto;
width: 100%;
height: 100%;
height:1em;
display:flex;
}
.active{
@ -56,7 +48,7 @@
input {
background:transparent;
width:100%;
width:2em;
}
.division-wrapper {
@ -64,13 +56,8 @@ input {
display: flex;
}
.beat {
height:1em;
display:flex;
flex:1 1 auto;
}
.suddivisione{
.suddivisione-content{
flex:1 1 auto;
border:none;
}

View file

@ -0,0 +1,101 @@
<template>
<div class="beat-wrapper">
<input v-model="divisioni" type="number" min="1" oninput="validity.valid||(value='');">
<!--- trovare modo per prevenire scrittura di input-->
<div class="division-wrapper">
<div class="beat" v-for="j in nDivisioni" :key='j' >
<!--<div>{{randomColori()}}</div>-->
<div class="suddivisione" :style="{'background-color': colore }" style="max-width:1em" :id="nome">{{titolo(j)}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'beat',
data() {
return {
nome:'',
colore: 'red',
divisioni: 1,
timing: 0
}
},
computed: {
nDivisioni() {
var n = parseInt(this.divisioni);
return isNaN(n) ? 0 : n;
}
},
methods: {
randomColori: function (){
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
// console.log(color);
this.colore = color;
},
getTime: function(){
// https://stackoverflow.com/questions/288699/get-the-position-of-a-div-span-tag#288731
var el = document.getElementById(this.nome);
for (var lx=0, ly=0;
el != null;
lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
console.log("x :"+ lx+", y :"+ly);
},
titolo(progressivo){
this.nome = "nomeBeat" + progressivo;
}
}
}
</script>
<style>
.beat{
flex: 1 1 auto;
width: 100%;
height: 100%;
}
.active{
background-color:black;
}
input {
background:transparent;
width:2em;
}
.division-wrapper {
flex:1 1 auto;
display: flex;
}
.beat {
height:1em;
display:flex;
flex:1 1 auto;
}
.suddivisione{
flex:1 1 auto;
border:none;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance:textfield;
padding-left:0.2em;
color:lightgray;
border:none;
}
</style>

18
components/sendButton.vue Normal file
View file

@ -0,0 +1,18 @@
<template>
<div class="send-wrapper">
<input type="submit" value="Submit">
<input type="button" style="width:5em;height:2em;background:red;color:white;" value="Send!">
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

View file

@ -1,26 +1,18 @@
<template>
<section class="sequencer" v-on:mouseover="displayControls()" v-on:mouseleave="hideControls()" >
<div class="sequencerLine">
<div class="slot-wrapper">
<div class="slot" v-for="i in slotSlider" :key='i' >
<beat v-if="euclideanList[i] === 1"></beat>
<div v-else class="activeSlot"></div>
<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>
</div>
<div>
<div class="control-menu" :class="[{'displayControls': controlIsDisplayed}]">
<range-slider class="slider" min="1" :max="maxSlots" step="1" v-model="slotSlider" v-on:input="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
<input id="pulseSlider" v-model="maxSlots" />
<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" v-model="assignBeat" />
<input id="pulseSlider" value="3" />
</div>
<!---
<div style="background-color:firebrick">
<input type="range" class="slider" min="1" max="32" step="1" v-model="slotSlider" v-on:change="assignEuclidean(slotSlider, pulseSlider)" />
<input type="range" class="slider" min="1" :max="slotSlider" step="1" v-model="pulseSlider" v-on:change="assignEuclidean(slotSlider, pulseSlider)" />
</div>
-->
</div>
</section>
</template>
@ -32,13 +24,17 @@
import beat from '~/components/beat.vue'
export default {
props: [ 'line' ],
data() {
return{
slotSlider: 16,
pulseSlider: 3,
euclideanList:[],
controlIsDisplayed:false
}
// return {
// id: line.id,
// slotSlider: line.slotSlider,
// pulseSlider: line.pulseSlider,
// euclideanList: line.euclideanList,
// controlIsDisplayed: line.controlIsDisplayed
// };
this.line.euclideanList = this.bjorklund(this.line.slotSlider, this.line.pulseSlider);
return this.line;
},
components: {
RangeSlider,
@ -86,7 +82,6 @@
return pattern.reverse();},
assignEuclidean: function (a,b) {
this.euclideanList = this.bjorklund(a,b);
console.log(this.euclideanList);
}
}
}
@ -140,6 +135,13 @@
display:flex !important;
}
.sequencerLine{
display:flex;
height:3em;
width:auto;
background-color:firebrick;
}
.slot-wrapper{
display:flex;
height:3em;

View file

@ -12,7 +12,7 @@
<range-slider class="slider" min="1" :max="maxSlots" step="1" v-model="slotSlider" v-on:input="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
<input id="pulseSlider" v-model="maxSlots" />
<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" v-model="assignBeat" />
<input id="pulseSlider" value="3" />
</div>
<!---
<div style="background-color:firebrick">

52
espify.sh Executable file
View file

@ -0,0 +1,52 @@
#!/bin/bash
prefix="dist"
flist="$(find $prefix -type f -name '*.js' -or -name 'index.html' -or -name 'favicon.ico' | sed -e 's/'$prefix'\/*//')"
get_var_name()
{
echo -e "static_$(echo -e $1 | tr -d '_' | tr '/.' '_')"
}
cat <<EOF
#include "gadgety.h"
#include <ESP8266WebServer.h>
EOF
for i in $flist; do
echo -e "unsigned char PROGMEM $(get_var_name $i)[] = {"
gzip -c "$prefix/$i" | xxd -i -c 16
echo -e "};\n"
done
cat <<EOF
static ESP8266WebServer *_server = 0;
#define SERVE_STATIC(p) static void serve_ ## p (void) { \\
_server->sendHeader("Content-Encoding", "gzip"); \\
_server->send_P(200, "text/html", (const char*)p, sizeof(p)); \\
}
static void redirect_index(void)
{
_server->sendHeader("Location", "/");
_server->send(301);
}
EOF
for i in $flist; do
echo -e "SERVE_STATIC($(get_var_name $i))"
done
echo -e "\nvoid gadgety_static_init_server(ESP8266WebServer* server)\n{"
echo -e " _server = server;"
echo -e " server->onNotFound(redirect_index);"
echo -e " server->on(\"/\", serve_static_index_html);"
for i in $flist; do
echo -e " server->on(\"/$i\", serve_$(get_var_name $i));"
done
echo -e "}"

Binary file not shown.

View file

@ -21,6 +21,14 @@ module.exports = {
** Build configuration
*/
build: {
filenames: {
css: 'common.css',
manifest: 'manifest.js',
vendor: 'common.js',
app: 'app.js',
chunk: '[name].js'
},
/*
** Run ESLint on save
*/
@ -36,4 +44,3 @@ module.exports = {
}
}
}

View file

@ -1,12 +1,18 @@
<template>
<div id="app">
<h2 class="subtitle">
<h2 id="titolone" class="subtitle" style="background:beige;position:absolute;bottom:0">
Second attempt at building a web interface for ESP8266
</h2>
<sequencer></sequencer>
<sequencer></sequencer>
<sequencer></sequencer>
<sequencer></sequencer>
<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>
</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">
@ -20,9 +26,7 @@
<div class="icon-button">
<img style="margin:auto;" src="~/assets/img/bell.png">
</div>
<div class="icon-button">
<img style="margin:auto;" src="~/assets/img/add.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>
@ -31,16 +35,55 @@
import sequencer from '~/components/sequencer.vue'
import sequencerDivided from '~/components/sequencerDivided.vue'
import beatMenu from '~/components/beatMenu.vue'
import moduleData from '~/assets/js/moduleData.json'
export default {
data() {
return {
lines: []
// https://stackoverflow.com/questions/44869287/set-object-in-data-from-a-method-in-vue-js#44869373
// creata object in data vue
}
},
components: {
sequencer,
sequencerDivided,
beatMenu
},
methods:
{
addLine: function (){
this.lines.push({
id: this.lines.length,
slotSlider: 16,
pulseSlider: 3,
euclideanList: [],
controlIsDisplayed: false });
},
getSequencerData: function(){
var modelEsp = {
'millis_per_slot': 500, // bpm = 60000 / millis_per_slot
'lines': this.lines.map(function(line) {
return line.euclideanList.reduce(function(acc, x) { return acc + x.toString(); }, '');
})
};
var xhr = new XMLHttpRequest();
xhr.open('POST', '/play.ws');
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200) {
//self.commits = JSON.parse(xhr.responseText);
console.log("Recv", xhr.responseText);
}
};
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(modelEsp));
}
}
}
</script>
<style>
.icon-button{
display:flex;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB