我正在尝试以具体的方式可视化音乐:
我构建了一个有 60 个键的键盘,我将其放置在画布的底部。按下的每个键的整个可视化都应该在此之上。
这个想法是,每触发一个键,就会创建一个新的椭圆。椭圆的颜色应该取决于具有特定颜色的键(例如,从左开始,从深紫色到亮黄色)。椭圆的整个彩色螺旋应该从中间开始,越来越多按键触发的每一个持续音调都更大。
(https://editor.p5js.org/Javrimir/sketches/JGx8-9kIF)
// 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;
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);
}
// 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);
upBuffer.ellipse(375,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(390,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(383,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(368,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(360,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(368,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(383,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(398,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(405,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(398,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(390,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(375,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(360,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(353,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(345,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(353,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(360,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(375,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(390,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(405,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(413,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(420,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(413,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(405,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(398,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(383,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(368,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(353,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(345,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(338,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(330,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(338,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(345,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(353,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(368,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(383,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(398,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(413,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(420,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(428,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(435,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(428,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(420,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(413,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(405,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(390,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(375,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(360,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(345,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(338,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(330,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(323,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(315,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(323,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(330,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(338,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(345,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(360,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(375,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(390,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(405,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(420,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(428,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(435,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(443,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(450,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(443,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(435,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(428,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(420,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(413,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(398,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(383,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(368,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(353,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(338,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(330,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(323,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(315,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(308,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(300,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(308,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(315,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(323,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(330,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(338,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(353,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(368,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(383,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(398,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(413,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(428,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(435,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(443,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(450,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(458,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(465,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(458,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(450,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(443,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(435,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(428,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(421,328,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(406,328,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(391,328,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(376,328,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(361,328,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(346,328,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(331,328,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(323,315,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(315,302,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(308,289,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(300,276,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(293,263,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(285,250,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(293,237,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(300,224,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(308,211,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(315,198,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(323,185,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(331,172,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(346,172,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(361,172,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(376,172,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(391,172,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(406,172,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
upBuffer.ellipse(421,172,15,15)
upBuffer.fill(255)
upBuffer.noStroke()
}
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);
}
// Draw the key
rect(x, 0, w-1, height-1);
}
}
实际上我已经制作了白色椭圆,所以它们需要在定义的方向上填充其他颜色,具体取决于按下的特殊键。背景也将是白色的,因此所描述的效果应该可以工作。
但仍然有松散的结局,我不知道如何连接。
- 如何在 p5.js 中执行以通过鼠标按特定顺序一一填充椭圆?
- 如何在按下鼠标的同时将使用的颜色与特定键组合?
如果有人能提供帮助并与我分享更多想法,我将不胜感激。
可选地,我还想知道是否会有更优雅的方式来创建椭圆而不是手动创建。