318 lines
7.7 KiB
Vue
318 lines
7.7 KiB
Vue
<template>
|
|
<section class="sequencer" >
|
|
<!--<span class="sequence-controls-wrapper">-->
|
|
<div class="options-wrapper">
|
|
<span class="control-bar" :style="{ opacity: barOpacity }">
|
|
<div class="sequence-options">
|
|
<div class="option-icon" id="icon-slots"></div>
|
|
<div class="option-icon" id="icon-euclid"></div>
|
|
<div class="sampleType-wrapper">
|
|
<div class="option-icon" id="icon-sample" @click="makeFirstChild(), selectSampleType(1)"></div>
|
|
<div class="option-icon" id="icon-sample" @click="makeFirstChild(), selectSampleType(2)"></div>
|
|
<div class="option-icon" id="icon-sample" @click="makeFirstChild(), selectSampleType(3)"></div>
|
|
<div class="option-icon" id="icon-sample" @click="makeFirstChild(), selectSampleType(4)"></div>
|
|
</div>
|
|
<div class="option-icon" id="icon-delete"></div>
|
|
</div>
|
|
<div class="sequence-bar">
|
|
<range-slider class="slider" @change="setFullOpacity()" min="1" step="1" v-model="slotSlider" v-on:input="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
|
|
<input id="pulseSlider"/>
|
|
<range-slider class="slider" @change="setFullOpacity()" min="1" :max="slotSlider" step="1" v-model="pulseSlider" v-on:input="assignEuclidean(slotSlider, pulseSlider)" ></range-slider>
|
|
<input id="pulseSlider" value="3" />
|
|
</div>
|
|
</span>
|
|
</div>
|
|
<div class="sequencerLine">
|
|
<div class="slot" v-for="(slot, slotid) in euclideanList" :key="slotid" :style="{ 'width': calculatePulseSize(line.sampleType) }">
|
|
<beat :id="'slot'+slotid" :line="line" v-if="slot === 1"></beat>
|
|
<div v-else class="emptySlot"></div>
|
|
</div>
|
|
</div>
|
|
<!--<</span>-->
|
|
<div>
|
|
<!--<div class="control-menu" style="margin-top:5em;" :class="[{'displayControls': controlIsDisplayed}]">-->
|
|
<div class="control-menu" style="margin-top:5em;">
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script>
|
|
import RangeSlider from 'vue-range-slider'
|
|
// you probably need to import built-in style
|
|
import 'vue-range-slider/dist/vue-range-slider.css'
|
|
import beat from '~/components/beat.vue'
|
|
|
|
export default {
|
|
props: [ 'line' ],
|
|
data() {
|
|
// 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;
|
|
},
|
|
watch: {
|
|
'slotSlider': function(){
|
|
this.barIsTransparent = true;
|
|
},
|
|
'pulseSlider': function(){
|
|
this.barIsTransparent = true;
|
|
},
|
|
'slotSlider': function(){
|
|
this.barOpacity = 0.5;
|
|
},
|
|
'pulseSlider': function(){
|
|
this.barOpacity = 0.5;
|
|
}
|
|
},
|
|
components: {
|
|
RangeSlider,
|
|
beat
|
|
},
|
|
methods: {
|
|
displayControls: function (){
|
|
this.controlIsDisplayed = true;
|
|
},
|
|
hideControls: function (){
|
|
this.controlIsDisplayed = false;
|
|
},
|
|
setFullOpacity: function (){
|
|
this.barOpacity = 1;
|
|
console.log("fullOPacity");
|
|
},
|
|
makeFirstChild: function (){
|
|
},
|
|
selectSampleType: function (number){
|
|
this.line.sampleType = number;
|
|
console.log(number);
|
|
},
|
|
calculatePulseSize(i) {
|
|
var pulseSize = ((this.sampleLengths[i]/this.line.sequenceMilliseconds)*100) + "vw";
|
|
return pulseSize;
|
|
},
|
|
bjorklund: function (slots, pulses) {
|
|
|
|
var pattern = [],
|
|
count = [],
|
|
remainder = [pulses],
|
|
divisor = slots - pulses,
|
|
level = 0,
|
|
build_pattern = function(lv) {
|
|
if (lv == -1) {
|
|
pattern.push(0);
|
|
} else if (lv == -2) {
|
|
pattern.push(1);
|
|
} else {
|
|
for (var x = 0; x < count[lv]; x++) {
|
|
build_pattern(lv - 1);
|
|
}
|
|
|
|
if (remainder[lv]) {
|
|
build_pattern(lv - 2);
|
|
}
|
|
}
|
|
}
|
|
while (remainder[level] > 1) {
|
|
count.push(Math.floor(divisor / remainder[level]));
|
|
remainder.push(divisor % remainder[level]);
|
|
divisor = remainder[level];
|
|
level++;
|
|
}
|
|
count.push(divisor);
|
|
|
|
build_pattern(level);
|
|
|
|
return pattern.reverse();},
|
|
assignEuclidean: function (a,b) {
|
|
this.euclideanList = this.bjorklund(a,b);
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.container {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
text-align: center;
|
|
}
|
|
|
|
.title {
|
|
font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
|
|
display: block;
|
|
font-weight: 300;
|
|
font-size: 100px;
|
|
color: #35495e;
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
.subtitle {
|
|
font-weight: 300;
|
|
font-size: 42px;
|
|
color: #526488;
|
|
word-spacing: 5px;
|
|
padding-bottom: 15px;
|
|
}
|
|
|
|
.links {
|
|
padding-top: 15px;
|
|
}
|
|
|
|
.active{
|
|
background-color:black;
|
|
width:100%;
|
|
height:40%
|
|
}
|
|
|
|
.control-menu{
|
|
display: none;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
.option-icon:hover{
|
|
background-color: cadetblue;
|
|
}
|
|
|
|
#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;
|
|
}
|
|
|
|
|
|
/*extend button for preventing menu from disappearing accidentally on the edge*/
|
|
.sampleType-wrapper::before {
|
|
content: "";
|
|
opacity: 0;
|
|
display: block;
|
|
width: 44px;
|
|
height: 10px;
|
|
position: absolute;
|
|
top: 0px;
|
|
left: 3px;
|
|
}
|
|
|
|
.sampleType-wrapper > .option-icon:not(:nth-child(1)){
|
|
display: none;
|
|
}
|
|
|
|
.sampleType-wrapper:hover > .option-icon{
|
|
display: block;
|
|
}
|
|
|
|
.sequencer{
|
|
display:flex;
|
|
}
|
|
|
|
.sequencerLine{
|
|
height:3em;
|
|
/*width:100%;*/
|
|
display:flex;
|
|
background-color:firebrick;
|
|
}
|
|
|
|
.slot-wrapper{
|
|
display:flex;
|
|
height:3em;
|
|
width:auto;
|
|
background-color:firebrick;
|
|
}
|
|
|
|
.slot{
|
|
flex:1 1 auto;
|
|
background-color:beige;
|
|
border-left:1pt solid aquamarine;
|
|
border-right:1pt solid aquamarine;
|
|
border-top: transparent !important;
|
|
border-bottom: transparent !important;
|
|
}
|
|
|
|
.activeSlot{
|
|
flex:1 1 auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
</style>
|