How to connect/trigger elements in specific mouse-pressed combinations in p5.js (piano)

Hello,

and welcome to the community and forum!

For the color in the function “function drawDownBuffer()” you can say:

fill(lerpColor( color(255,0,0), color(0,0,255), i/notes.length ))

Next

You can store the ellipse position
in a list. That’s still manually but you can work much better with an array.
(I think the calculation of the positions mathematically is not trivial)

When you display the array you can use a color. I did this.

You can store the colors in a
parallel array. I haven’t done this.
Then you can put all colors in the spiral to white and the pressed ellipse to its color.

Please try my code below.

In the 2nd version the ellipse in the spiral is highlighted. This is possible because the index of the piano below (the key variable) is the same as the index in spiral above.

You wrote:

Not sure what you mean by particular order. Is the user supposed to play a certain song? Then you could store the index in a new array (similar to notes but representing the indexes for notes) and compare the user input to it (wrong or correct index been played).

I hope I did this in the 2nd version.


Nice project!

I hope this helps!

Warm regards,

Chrisir


Full Code (1)

// The midi notes of a scale
var notes = [
  40,
  41,
  42,
  43,
  44,
  45,
  46,
  47,
  48,
  49,
  50,
  51,
  52,
  53,
  54,
  55,
  56,
  57,
  58,
  59,
  60,
  61,
  62,
  63,
  64,
  65,
  66,
  67,
  68,
  69,
  70,
  71,
  72,
  73,
  74,
  75,
  76,
  77,
  78,
  79,
  80,
  81,
  82,
  83,
  84,
  85,
  86,
  87,
  88,
  89,
  90,
  91,
  92,
  93,
  94,
  95,
  96,
  97,
  98,
  99,
];
var osc;

var upBuffer;
var downBuffer;

let list = [new p5.Vector(375, 250)];

function setup() {
  // 800 x 600 (double width to make room for each "sub-canvas")
  createCanvas(750, 600);
  // Create both of your off-screen graphics buffers
  upBuffer = createGraphics(750, 500);
  downBuffer = createGraphics(750, 100);

  // A triangle oscillator
  osc = new p5.TriOsc();
  // Start silent
  osc.start();
  osc.amp(0);

  //  append(list, new new p5.Vector(375,250) );

  append(list, new p5.Vector(390, 250, 15, 15));
  append(list, new p5.Vector(383, 263, 15, 15));
  append(list, new p5.Vector(368, 263, 15, 15));
  append(list, new p5.Vector(360, 250, 15, 15));
  append(list, new p5.Vector(368, 237, 15, 15));
  append(list, new p5.Vector(383, 237, 15, 15));
  append(list, new p5.Vector(398, 237, 15, 15));
  append(list, new p5.Vector(405, 250, 15, 15));
  append(list, new p5.Vector(398, 263, 15, 15));
  append(list, new p5.Vector(390, 276, 15, 15));
  append(list, new p5.Vector(375, 276, 15, 15));
  append(list, new p5.Vector(360, 276, 15, 15));
  append(list, new p5.Vector(353, 263, 15, 15));
  append(list, new p5.Vector(345, 250, 15, 15));
  append(list, new p5.Vector(353, 237, 15, 15));
  append(list, new p5.Vector(360, 224, 15, 15));
  append(list, new p5.Vector(375, 224, 15, 15));
  append(list, new p5.Vector(390, 224, 15, 15));
  append(list, new p5.Vector(405, 224, 15, 15));
  append(list, new p5.Vector(413, 237, 15, 15));
  append(list, new p5.Vector(420, 250, 15, 15));
  append(list, new p5.Vector(413, 263, 15, 15));
  append(list, new p5.Vector(405, 276, 15, 15));
  append(list, new p5.Vector(398, 289, 15, 15));
  append(list, new p5.Vector(383, 289, 15, 15));
  append(list, new p5.Vector(368, 289, 15, 15));
  append(list, new p5.Vector(353, 289, 15, 15));
  append(list, new p5.Vector(345, 276, 15, 15));
  append(list, new p5.Vector(338, 263, 15, 15));
  append(list, new p5.Vector(330, 250, 15, 15));
  append(list, new p5.Vector(338, 237, 15, 15));
  append(list, new p5.Vector(345, 224, 15, 15));
  append(list, new p5.Vector(353, 211, 15, 15));
  append(list, new p5.Vector(368, 211, 15, 15));
  append(list, new p5.Vector(383, 211, 15, 15));
  append(list, new p5.Vector(398, 211, 15, 15));
  append(list, new p5.Vector(413, 211, 15, 15));
  append(list, new p5.Vector(420, 224, 15, 15));
  append(list, new p5.Vector(428, 237, 15, 15));
  append(list, new p5.Vector(435, 250, 15, 15));
  append(list, new p5.Vector(428, 263, 15, 15));
  append(list, new p5.Vector(420, 276, 15, 15));
  append(list, new p5.Vector(413, 289, 15, 15));
  append(list, new p5.Vector(405, 302, 15, 15));
  append(list, new p5.Vector(390, 302, 15, 15));
  append(list, new p5.Vector(375, 302, 15, 15));
  append(list, new p5.Vector(360, 302, 15, 15));
  append(list, new p5.Vector(345, 302, 15, 15));
  append(list, new p5.Vector(338, 289, 15, 15));
  append(list, new p5.Vector(330, 276, 15, 15));
  append(list, new p5.Vector(323, 263, 15, 15));
  append(list, new p5.Vector(315, 250, 15, 15));
  append(list, new p5.Vector(323, 237, 15, 15));
  append(list, new p5.Vector(330, 224, 15, 15));
  append(list, new p5.Vector(338, 211, 15, 15));
  append(list, new p5.Vector(345, 198, 15, 15));
  append(list, new p5.Vector(360, 198, 15, 15));
  append(list, new p5.Vector(375, 198, 15, 15));
  append(list, new p5.Vector(390, 198, 15, 15));
  append(list, new p5.Vector(405, 198, 15, 15));
  append(list, new p5.Vector(420, 198, 15, 15));
  append(list, new p5.Vector(428, 211, 15, 15));
  append(list, new p5.Vector(435, 224, 15, 15));
  append(list, new p5.Vector(443, 237, 15, 15));
  append(list, new p5.Vector(450, 250, 15, 15));
  append(list, new p5.Vector(443, 263, 15, 15));
  append(list, new p5.Vector(435, 276, 15, 15));
  append(list, new p5.Vector(428, 289, 15, 15));
  append(list, new p5.Vector(420, 302, 15, 15));
  append(list, new p5.Vector(413, 315, 15, 15));
  append(list, new p5.Vector(398, 315, 15, 15));
  append(list, new p5.Vector(383, 315, 15, 15));
  append(list, new p5.Vector(368, 315, 15, 15));
  append(list, new p5.Vector(353, 315, 15, 15));
  append(list, new p5.Vector(338, 315, 15, 15));
  append(list, new p5.Vector(330, 302, 15, 15));
  append(list, new p5.Vector(323, 289, 15, 15));
  append(list, new p5.Vector(315, 276, 15, 15));
  append(list, new p5.Vector(308, 263, 15, 15));
  append(list, new p5.Vector(300, 250, 15, 15));
  append(list, new p5.Vector(308, 237, 15, 15));
  append(list, new p5.Vector(315, 224, 15, 15));
  append(list, new p5.Vector(323, 211, 15, 15));
  append(list, new p5.Vector(330, 198, 15, 15));
  append(list, new p5.Vector(338, 185, 15, 15));
  append(list, new p5.Vector(353, 185, 15, 15));
  append(list, new p5.Vector(368, 185, 15, 15));
  append(list, new p5.Vector(383, 185, 15, 15));
  append(list, new p5.Vector(398, 185, 15, 15));
  append(list, new p5.Vector(413, 185, 15, 15));
  append(list, new p5.Vector(428, 185, 15, 15));
  append(list, new p5.Vector(435, 198, 15, 15));
  append(list, new p5.Vector(443, 211, 15, 15));
  append(list, new p5.Vector(450, 224, 15, 15));
  append(list, new p5.Vector(458, 237, 15, 15));
  append(list, new p5.Vector(465, 250, 15, 15));
  append(list, new p5.Vector(458, 263, 15, 15));
  append(list, new p5.Vector(450, 276, 15, 15));
  append(list, new p5.Vector(443, 289, 15, 15));
  append(list, new p5.Vector(435, 302, 15, 15));
  append(list, new p5.Vector(428, 315, 15, 15));
  append(list, new p5.Vector(421, 328, 15, 15));
  append(list, new p5.Vector(406, 328, 15, 15));
  append(list, new p5.Vector(391, 328, 15, 15));
  append(list, new p5.Vector(376, 328, 15, 15));
  append(list, new p5.Vector(361, 328, 15, 15));
  append(list, new p5.Vector(346, 328, 15, 15));
  append(list, new p5.Vector(331, 328, 15, 15));
  append(list, new p5.Vector(323, 315, 15, 15));
  append(list, new p5.Vector(315, 302, 15, 15));
  append(list, new p5.Vector(308, 289, 15, 15));
  append(list, new p5.Vector(300, 276, 15, 15));
  append(list, new p5.Vector(293, 263, 15, 15));
  append(list, new p5.Vector(285, 250, 15, 15));
  append(list, new p5.Vector(293, 237, 15, 15));
  append(list, new p5.Vector(300, 224, 15, 15));
  append(list, new p5.Vector(308, 211, 15, 15));
  append(list, new p5.Vector(315, 198, 15, 15));
  append(list, new p5.Vector(323, 185, 15, 15));
  append(list, new p5.Vector(331, 172, 15, 15));
  append(list, new p5.Vector(346, 172, 15, 15));
  append(list, new p5.Vector(361, 172, 15, 15));
  append(list, new p5.Vector(376, 172, 15, 15));
  append(list, new p5.Vector(391, 172, 15, 15));
  append(list, new p5.Vector(406, 172, 15, 15));
  append(list, new p5.Vector(421, 172, 15, 15));
}

// A function to play a note
function playNote(note, duration) {
  osc.freq(midiToFreq(note));
  // Fade it in
  osc.fade(0.5, 0.2);

  // If we sest a duration, fade it out
  if (duration) {
    setTimeout(function () {
      osc.fade(0, 0.2);
    }, duration - 50);
  }
}

// When we click
function mousePressed() {
  // Map mouse to the key index
  var key = floor(map(mouseX, 0, width, 0, notes.length));
  playNote(notes[key]);
}

// Fade it out when we release
function mouseReleased() {
  osc.fade(0, 0.5);
}

function draw() {
  // Draw on your buffers however you like
  drawUpBuffer();
  drawDownBuffer();
  // Paint the off-screen buffers onto the main canvas
  image(upBuffer, 0, 0);
  image(downBuffer, 0, 500);
}

function drawUpBuffer() {
  upBuffer.background(155);

  for (let i = 0; i < list.length; i++) {
    //
    upBuffer.fill(lerpColor(color(255, 0, 0), color(0, 0, 255), i / notes.length));
    upBuffer.ellipse(list[i].x, list[i].y, 15, 15);
  }
}

function drawDownBuffer() {
  // Draw a keyboard

  // The width for each key
  var w = width / notes.length;
  for (var i = 0; i < notes.length; i++) {
    var x = i * w;
    // If the mouse is over the key
    if (mouseX > x && mouseX < x + w && mouseY < height) {
      // If we're clicking
      if (mouseIsPressed) {
        fill(100, 255, 200);
        // Or just rolling over
      } else {
        fill(127);
      }
    } else {
      fill(200);
    }

    fill(lerpColor(color(255, 0, 0), color(0, 0, 255), i / notes.length));

    // Draw the key
    rect(x, 0, w - 1, height - 1);
  }
}
//


NEW VERSION (2)

// The midi notes of a scale
var notes = [
  40,
  41,
  42,
  43,
  44,
  45,
  46,
  47,
  48,
  49,
  50,
  51,
  52,
  53,
  54,
  55,
  56,
  57,
  58,
  59,
  60,
  61,
  62,
  63,
  64,
  65,
  66,
  67,
  68,
  69,
  70,
  71,
  72,
  73,
  74,
  75,
  76,
  77,
  78,
  79,
  80,
  81,
  82,
  83,
  84,
  85,
  86,
  87,
  88,
  89,
  90,
  91,
  92,
  93,
  94,
  95,
  96,
  97,
  98,
  99,
];
var osc;

var upBuffer;
var downBuffer;

let list = [new p5.Vector(375, 250)];

var key;

var playingNote = false;

function setup() {
  // 800 x 600 (double width to make room for each "sub-canvas")
  createCanvas(750, 600);
  // Create both of your off-screen graphics buffers
  upBuffer = createGraphics(750, 500);
  downBuffer = createGraphics(750, 100);

  // A triangle oscillator
  osc = new p5.TriOsc();
  // Start silent
  osc.start();
  osc.amp(0);

  //  append(list, new new p5.Vector(375,250) );

  append(list, new p5.Vector(390, 250, 15, 15));
  append(list, new p5.Vector(383, 263, 15, 15));
  append(list, new p5.Vector(368, 263, 15, 15));
  append(list, new p5.Vector(360, 250, 15, 15));
  append(list, new p5.Vector(368, 237, 15, 15));
  append(list, new p5.Vector(383, 237, 15, 15));
  append(list, new p5.Vector(398, 237, 15, 15));
  append(list, new p5.Vector(405, 250, 15, 15));
  append(list, new p5.Vector(398, 263, 15, 15));
  append(list, new p5.Vector(390, 276, 15, 15));
  append(list, new p5.Vector(375, 276, 15, 15));
  append(list, new p5.Vector(360, 276, 15, 15));
  append(list, new p5.Vector(353, 263, 15, 15));
  append(list, new p5.Vector(345, 250, 15, 15));
  append(list, new p5.Vector(353, 237, 15, 15));
  append(list, new p5.Vector(360, 224, 15, 15));
  append(list, new p5.Vector(375, 224, 15, 15));
  append(list, new p5.Vector(390, 224, 15, 15));
  append(list, new p5.Vector(405, 224, 15, 15));
  append(list, new p5.Vector(413, 237, 15, 15));
  append(list, new p5.Vector(420, 250, 15, 15));
  append(list, new p5.Vector(413, 263, 15, 15));
  append(list, new p5.Vector(405, 276, 15, 15));
  append(list, new p5.Vector(398, 289, 15, 15));
  append(list, new p5.Vector(383, 289, 15, 15));
  append(list, new p5.Vector(368, 289, 15, 15));
  append(list, new p5.Vector(353, 289, 15, 15));
  append(list, new p5.Vector(345, 276, 15, 15));
  append(list, new p5.Vector(338, 263, 15, 15));
  append(list, new p5.Vector(330, 250, 15, 15));
  append(list, new p5.Vector(338, 237, 15, 15));
  append(list, new p5.Vector(345, 224, 15, 15));
  append(list, new p5.Vector(353, 211, 15, 15));
  append(list, new p5.Vector(368, 211, 15, 15));
  append(list, new p5.Vector(383, 211, 15, 15));
  append(list, new p5.Vector(398, 211, 15, 15));
  append(list, new p5.Vector(413, 211, 15, 15));
  append(list, new p5.Vector(420, 224, 15, 15));
  append(list, new p5.Vector(428, 237, 15, 15));
  append(list, new p5.Vector(435, 250, 15, 15));
  append(list, new p5.Vector(428, 263, 15, 15));
  append(list, new p5.Vector(420, 276, 15, 15));
  append(list, new p5.Vector(413, 289, 15, 15));
  append(list, new p5.Vector(405, 302, 15, 15));
  append(list, new p5.Vector(390, 302, 15, 15));
  append(list, new p5.Vector(375, 302, 15, 15));
  append(list, new p5.Vector(360, 302, 15, 15));
  append(list, new p5.Vector(345, 302, 15, 15));
  append(list, new p5.Vector(338, 289, 15, 15));
  append(list, new p5.Vector(330, 276, 15, 15));
  append(list, new p5.Vector(323, 263, 15, 15));
  append(list, new p5.Vector(315, 250, 15, 15));
  append(list, new p5.Vector(323, 237, 15, 15));
  append(list, new p5.Vector(330, 224, 15, 15));
  append(list, new p5.Vector(338, 211, 15, 15));
  append(list, new p5.Vector(345, 198, 15, 15));
  append(list, new p5.Vector(360, 198, 15, 15));
  append(list, new p5.Vector(375, 198, 15, 15));
  append(list, new p5.Vector(390, 198, 15, 15));
  append(list, new p5.Vector(405, 198, 15, 15));
  append(list, new p5.Vector(420, 198, 15, 15));
  append(list, new p5.Vector(428, 211, 15, 15));
  append(list, new p5.Vector(435, 224, 15, 15));
  append(list, new p5.Vector(443, 237, 15, 15));
  append(list, new p5.Vector(450, 250, 15, 15));
  append(list, new p5.Vector(443, 263, 15, 15));
  append(list, new p5.Vector(435, 276, 15, 15));
  append(list, new p5.Vector(428, 289, 15, 15));
  append(list, new p5.Vector(420, 302, 15, 15));
  append(list, new p5.Vector(413, 315, 15, 15));
  append(list, new p5.Vector(398, 315, 15, 15));
  append(list, new p5.Vector(383, 315, 15, 15));
  append(list, new p5.Vector(368, 315, 15, 15));
  append(list, new p5.Vector(353, 315, 15, 15));
  append(list, new p5.Vector(338, 315, 15, 15));
  append(list, new p5.Vector(330, 302, 15, 15));
  append(list, new p5.Vector(323, 289, 15, 15));
  append(list, new p5.Vector(315, 276, 15, 15));
  append(list, new p5.Vector(308, 263, 15, 15));
  append(list, new p5.Vector(300, 250, 15, 15));
  append(list, new p5.Vector(308, 237, 15, 15));
  append(list, new p5.Vector(315, 224, 15, 15));
  append(list, new p5.Vector(323, 211, 15, 15));
  append(list, new p5.Vector(330, 198, 15, 15));
  append(list, new p5.Vector(338, 185, 15, 15));
  append(list, new p5.Vector(353, 185, 15, 15));
  append(list, new p5.Vector(368, 185, 15, 15));
  append(list, new p5.Vector(383, 185, 15, 15));
  append(list, new p5.Vector(398, 185, 15, 15));
  append(list, new p5.Vector(413, 185, 15, 15));
  append(list, new p5.Vector(428, 185, 15, 15));
  append(list, new p5.Vector(435, 198, 15, 15));
  append(list, new p5.Vector(443, 211, 15, 15));
  append(list, new p5.Vector(450, 224, 15, 15));
  append(list, new p5.Vector(458, 237, 15, 15));
  append(list, new p5.Vector(465, 250, 15, 15));
  append(list, new p5.Vector(458, 263, 15, 15));
  append(list, new p5.Vector(450, 276, 15, 15));
  append(list, new p5.Vector(443, 289, 15, 15));
  append(list, new p5.Vector(435, 302, 15, 15));
  append(list, new p5.Vector(428, 315, 15, 15));
  append(list, new p5.Vector(421, 328, 15, 15));
  append(list, new p5.Vector(406, 328, 15, 15));
  append(list, new p5.Vector(391, 328, 15, 15));
  append(list, new p5.Vector(376, 328, 15, 15));
  append(list, new p5.Vector(361, 328, 15, 15));
  append(list, new p5.Vector(346, 328, 15, 15));
  append(list, new p5.Vector(331, 328, 15, 15));
  append(list, new p5.Vector(323, 315, 15, 15));
  append(list, new p5.Vector(315, 302, 15, 15));
  append(list, new p5.Vector(308, 289, 15, 15));
  append(list, new p5.Vector(300, 276, 15, 15));
  append(list, new p5.Vector(293, 263, 15, 15));
  append(list, new p5.Vector(285, 250, 15, 15));
  append(list, new p5.Vector(293, 237, 15, 15));
  append(list, new p5.Vector(300, 224, 15, 15));
  append(list, new p5.Vector(308, 211, 15, 15));
  append(list, new p5.Vector(315, 198, 15, 15));
  append(list, new p5.Vector(323, 185, 15, 15));
  append(list, new p5.Vector(331, 172, 15, 15));
  append(list, new p5.Vector(346, 172, 15, 15));
  append(list, new p5.Vector(361, 172, 15, 15));
  append(list, new p5.Vector(376, 172, 15, 15));
  append(list, new p5.Vector(391, 172, 15, 15));
  append(list, new p5.Vector(406, 172, 15, 15));
  append(list, new p5.Vector(421, 172, 15, 15));
}

// A function to play a note
function playNote(note, duration) {
  osc.freq(midiToFreq(note));
  // Fade it in
  osc.fade(0.5, 0.2);

  // If we sest a duration, fade it out
  if (duration) {
    setTimeout(function () {
      osc.fade(0, 0.2);
    }, duration - 50);
  }
}

// When we click
function mousePressed() {
  // Map mouse to the key index
  key = floor(map(mouseX, 0, width, 0, notes.length));
  playNote(notes[key]);
  //fill(255, 22, 22);
  //upBuffer.ellipse(list[key].x, list[key].y, 15, 15);
  playingNote = true;
}

// Fade it out when we release
function mouseReleased() {
  osc.fade(0, 0.5);
  playingNote = false;
}

function draw() {
  // Draw on your buffers however you like
  drawUpBuffer();
  drawDownBuffer();
  // Paint the off-screen buffers onto the main canvas
  image(upBuffer, 0, 0);
  image(downBuffer, 0, 500);
}

function drawUpBuffer() {
  upBuffer.background(155);

  for (let i = 0; i < list.length; i++) {
    //
    // upBuffer.fill(lerpColor(color(255, 0, 0), color(0, 0, 255), i / notes.length));
    upBuffer.fill(222);
    if (playingNote && i == key)
      upBuffer.fill(
        lerpColor(color(255, 0, 0), color(0, 0, 255), key / notes.length)
      );
    upBuffer.ellipse(list[i].x, list[i].y, 15, 15);
  }
}

function drawDownBuffer() {
  // Draw a keyboard

  // The width for each key
  var w = width / notes.length;
  for (var i = 0; i < notes.length; i++) {
    var x = i * w;
    // If the mouse is over the key
    if (mouseX > x && mouseX < x + w && mouseY < height) {
      // If we're clicking
      if (mouseIsPressed) {
        fill(100, 255, 200);
        // Or just rolling over
      } else {
        fill(127);
      }
    } else {
      fill(200);
    }

    fill(lerpColor(color(255, 0, 0), color(0, 0, 255), i / notes.length));

    // Draw the key
    rect(x, 0, w - 1, height - 1);
  }
}
//

1 Like