<script>
  $(document).ready(function() {
    $("body").on("contextmenu", function(e) {
      return false;
    });
  });

</script>

<?xml version="1.0" encoding="UTF-8"?>
<svg width="100%" height="100%" viewBox="0 0 11500 9500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>12 Chord buttons II</title>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <rect id="Rectangle" fill="#000000" x="0" y="0" width="11500" height="9500"></rect>
        <g id="Background" transform="translate(1250.000000, 1300.000000)" stroke-linejoin="round" stroke-width="100">
            <rect id="ET7B" stroke="#90BE6D" fill="#90BE6D" x="7950" y="-50" width="1100" height="1100"></rect>
            <rect id="ETmin7B" stroke="#90BE6D" fill="#90BE6D" x="5950" y="-50" width="1100" height="1100"></rect>
            <rect id="ETmaj7B" stroke="#90BE6D" fill="#90BE6D" x="3950" y="-50" width="1100" height="1100"></rect>
            <rect id="ETminB" stroke="#90BE6D" fill="#90BE6D" x="1950" y="-50" width="1100" height="1100"></rect>
            <rect id="ETmajB" stroke="#90BE6D" fill="#90BE6D" x="-50" y="-50" width="1100" height="1100"></rect>
            <rect id="JI7B" stroke="#F3722C" fill="#F3722C" x="7950" y="5850" width="1100" height="1100"></rect>
            <rect id="JImin7B" stroke="#F3722C" fill="#F3722C" x="5950" y="5850" width="1100" height="1100"></rect>
            <rect id="JImaj7B" stroke="#F3722C" fill="#F3722C" x="3950" y="5850" width="1100" height="1100"></rect>
            <rect id="JIminB" stroke="#F3722C" fill="#F3722C" x="1950" y="5850" width="1100" height="1100"></rect>
            <rect id="JImajB" stroke="#F3722C" fill="#F3722C" x="-50" y="5850" width="1100" height="1100"></rect>
        </g>
        <g id="Text" transform="translate(1000.000000, 1300.000000)" fill="#FFFFFF" font-family="AvenirNext-Regular, Avenir Next" font-size="450" font-weight="normal">
            <text id="Ratios-Maj">
                <tspan x="405.75" y="4150">3/2</tspan>
                <tspan x="405.75" y="4765">5/4</tspan>
                <tspan x="405.75" y="5380">1/1</tspan>
            </text>
            <text id="Ratios-7">
                <tspan x="8405.75" y="3650">7/4</tspan>
                <tspan x="8405.75" y="4265">3/2</tspan>
                <tspan x="8405.75" y="4880">5/4</tspan>
                <tspan x="8405.75" y="5495">1/1</tspan>
            </text>
            <text id="Ratios-Min">
                <tspan x="2405.75" y="4150">3/2</tspan>
                <tspan x="2405.75" y="4765">6/5</tspan>
                <tspan x="2405.75" y="5380">1/1</tspan>
            </text>
            <text id="Ratios-Min7">
                <tspan x="6405.75" y="3650">9/5</tspan>
                <tspan x="6405.75" y="4265">3/2</tspan>
                <tspan x="6405.75" y="4880">6/5</tspan>
                <tspan x="6405.75" y="5495">1/1</tspan>
            </text>
            <text id="Ratios-Maj7">
                <tspan x="4275.25" y="3650">15/8</tspan>
                <tspan x="4405.75" y="4265">3/2</tspan>
                <tspan x="4405.75" y="4880">5/4</tspan>
                <tspan x="4405.75" y="5495">1/1</tspan>
            </text>
            <text id="Dom.-7th">
                <tspan x="8191.775" y="1650">Dom. </tspan>
                <tspan x="8417" y="2265">7th</tspan>
            </text>
            <text id="Minor-7th">
                <tspan x="6145.2" y="1650">Minor</tspan>
                <tspan x="6417" y="2265">7th</tspan>
            </text>
            <text id="Major-7th">
                <tspan x="4155.55" y="1650">Major</tspan>
                <tspan x="4417" y="2265">7th</tspan>
            </text>
            <text id="Minor-triad">
                <tspan x="2145.2" y="1650">Minor </tspan>
                <tspan x="2277.95" y="2265">triad</tspan>
            </text>
            <text id="Major-triad">
                <tspan x="155.55" y="1650">Major </tspan>
                <tspan x="277.95" y="2265">triad</tspan>
            </text>
            <text id="JI">
                <tspan x="580.8" y="6550">JI</tspan>
            </text>
            <text id="JI-Copy">
                <tspan x="2580.8" y="6550">JI</tspan>
            </text>
            <text id="JI-Copy-2">
                <tspan x="4580.8" y="6550">JI</tspan>
            </text>
            <text id="JI-Copy-3">
                <tspan x="6580.8" y="6550">JI</tspan>
            </text>
            <text id="JI-Copy-4">
                <tspan x="8580.8" y="6550">JI</tspan>
            </text>
            <text id="ET5">
                <tspan x="488.55" y="650">ET</tspan>
            </text>
            <text id="ET4">
                <tspan x="2488.55" y="650">ET</tspan>
            </text>
            <text id="ET3">
                <tspan x="4489.55" y="650">ET</tspan>
            </text>
            <text id="ET2">
                <tspan x="6488.55" y="650">ET</tspan>
            </text>
            <text id="ET1">
                <tspan x="8488.55" y="650">ET</tspan>
            </text>
        </g>
        <g id="Lines" transform="translate(1075.000000, 1125.000000)" stroke="#FFFFFF" stroke-width="25">
            <rect id="Rectangle" x="-12.5" y="-12.5" width="1375" height="7275" rx="100"></rect>
            <rect id="Rectangle-Copy-5" x="1987.5" y="-12.5" width="1375" height="7275" rx="100"></rect>
            <rect id="Rectangle-Copy-6" x="3987.5" y="-12.5" width="1375" height="7275" rx="100"></rect>
            <rect id="Rectangle-Copy-7" x="5987.5" y="-12.5" width="1375" height="7275" rx="100"></rect>
            <rect id="Rectangle-Copy-8" x="7987.5" y="-12.5" width="1375" height="7275" rx="100"></rect>
        </g>
        <g id="Keys" transform="translate(1250.000000, 1300.000000)" fill="#000000" fill-opacity="0">
<rect id="ET7" x="7900" y="-75" width="1150" height="1150"></rect>
<rect id="ETmin7" x="5900" y="-100" width="1200" height="1200"></rect>
<rect id="ETmaj7" x="3900" y="-100" width="1200" height="1200"></rect>
<rect id="ETmin" x="1900" y="-100" width="1200" height="1200"></rect>
<rect id="ETmaj" x="-100" y="-100" width="1200" height="1200"></rect>
<rect id="JI7" x="7900" y="5800" width="1200" height="1200"></rect>
<rect id="JImin7" x="5900" y="5800" width="1200" height="1200"></rect>
<rect id="JImaj7" x="3900" y="5800" width="1200" height="1200"></rect>
<rect id="JImin" x="1900" y="5800" width="1200" height="1200"></rect>
<rect id="JImaj" x="-100" y="5800" width="1200" height="1200"></rect>
        </g>
    </g>
</svg>
body {
  background-color: #000000;
  font-family: Avenir next;
  font-size: 100%;
  user-select: none;
  touch-action: none;
}

svg{
  display:block;
  position: absolute;
  z-index:0;
  height: 100%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  touch-action: none;
  background-color: #000000;
}


/* Portrait orientation */
/*
@media screen and (orientation: portrait) {
button{
  display: block;
  position: absolute;
  background-color:#000000;
  font-family: avenir next;
  border-radius: 2px;
  border-width: 2px;
  border-style: solid;
  user-select: none;
  height: 7%;
  width: 17%;
  right: 2%;
  z-index: 3;
  font-size: 2vw
}
}
*/
/* Landscape orientation */
/*@media screen and (orientation: landscape) {*/
button{
  display: block;
  position: absolute;
  background-color:#000000;
  font-family: avenir next;
  border-radius: 4px;
  border-width: 2px;
  border-style: solid;
  user-select: none;
  height: 10%;
  width: 15%;
  right: 2%;
  z-index: 3;
  font-size: 2.5vw
}
/*}*/

.ActiveButton {
  color: #000000;
  background-color: #577590;
  border-color: #577590;
}

.OtherButton {
  color: #577590;
  background-color: #000000;
  border-color: #577590;
}

#PureButton {
  top: 35%;
  left: 10%
}

#ReducedButton{
  top: 55%;
  left: 10%
}

#SelectorText{
  display: none;
  position: absolute;
  left: 5%;
  top: 8%;
  color: #ffffff;
  z-index: 5
}
// General

console.clear(); 

var elem = document.documentElement;


const baseFreq = 261.63
var root = baseFreq
var transpose=0
var voice = 0
var maxVoices = 4
var KeyArray = []
let index

//*** initialize tone.js synth ***

     // core synthesizer
const voice1 = new Tone.Synth({oscillator: {type:"triangle"},
  envelope: { attack : 0.05, decay : 3.50, sustain : 1, release : 7.5}, 
  volume: -12});

const voice2 = new Tone.Synth({oscillator: {type:"triangle"},
  envelope: { attack : 0.05, decay : 3.50, sustain : 1, release : 7.5}, 
  volume: -12});

const voice3 = new Tone.Synth({oscillator: {type:"triangle"},
  envelope: { attack : 0.05, decay : 3.50, sustain : 1, release : 7.5}, 
  volume: -12});

const voice4 = new Tone.Synth({oscillator: {type:"triangle"},
  envelope: { attack : 0.05, decay : 3.50, sustain : 1, release : 7.5}, 
  volume: -12});

const synth = [voice1, voice2, voice3, voice4]



const reverb = new Tone.Reverb({wet:0.5}).toDestination();

Tone.connect(voice1, reverb);
Tone.connect(voice2, reverb);
Tone.connect(voice3, reverb);
Tone.connect(voice4, reverb);


      
// Interaction mode

let isTouchDevice
var interaction = 'click'

if ((navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)){isTouchDevice = true}
else {isTouchDevice = false}
    
if (isTouchDevice) {interaction = 'touchstart'}



// Make array of key elements by id

for(var i=0, n=document.getElementsByClassName("key"); i<n.length; i++) {
   KeyArray.push(n[i].id);
   };



// Trigger notes

//Tone.Transport.start()

function triggerNoteOnOff(value) {
 
synth[voice].triggerAttackRelease(root*math.eval(value), "32n");
  
if (voice >= (maxVoices-1)){voice = 0}
else {voice ++}
 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
  
}
  
Tone.Transport.bpm.value = 80

document.getElementById("JImaj").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*eval(5/4), "2n"); 
        voice3.triggerAttackRelease(root*eval(3/2), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("ETmaj").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*Math.pow(2, 4/12), "2n"); 
        voice3.triggerAttackRelease(root*Math.pow(2, 7/12), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("JImin").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*eval(6/5), "2n"); 
        voice3.triggerAttackRelease(root*eval(3/2), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("ETmin").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*Math.pow(2, 3/12), "2n"); 
        voice3.triggerAttackRelease(root*Math.pow(2, 7/12), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("JImaj7").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*eval(5/4), "2n"); 
        voice3.triggerAttackRelease(root*eval(3/2), "2n"); 
        voice4.triggerAttackRelease(root*eval(15/8), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("ETmaj7").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*Math.pow(2, 4/12), "2n"); 
        voice3.triggerAttackRelease(root*Math.pow(2, 7/12), "2n"); 
        voice4.triggerAttackRelease(root*Math.pow(2, 11/12), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("JImin7").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*eval(6/5), "2n"); 
        voice3.triggerAttackRelease(root*eval(3/2), "2n"); 
        voice4.triggerAttackRelease(root*eval(9/5), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("ETmin7").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*Math.pow(2, 3/12), "2n"); 
        voice3.triggerAttackRelease(root*Math.pow(2, 7/12), "2n"); 
        voice4.triggerAttackRelease(root*Math.pow(2, 10/12), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("JI7").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*eval(5/4), "2n"); 
        voice3.triggerAttackRelease(root*eval(3/2), "2n"); 
        voice4.triggerAttackRelease(root*eval(7/4), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

document.getElementById("ET7").addEventListener('click', function(){
        voice1.triggerAttackRelease(root, "2n"); 
        voice2.triggerAttackRelease(root*Math.pow(2, 4/12), "2n"); 
        voice3.triggerAttackRelease(root*Math.pow(2, 7/12), "2n"); 
        voice4.triggerAttackRelease(root*Math.pow(2, 10/12), "2n"); 
  this.style.fillOpacity=0.5
  const key = this.id;
  function resetOpacity(key){
    document.getElementById(key).style.fillOpacity=0}
  setTimeout(function(){resetOpacity(key)}, 200)
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.