D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
SpaceActuary
Full window
Github gist
Music Viz
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="tones.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } </style> </head> <body> <script> // Feel free to change or delete any of the code you see in this editor! var size = 10; var svg = d3.select("body").append("svg") .attr("width", 960) .attr("height", 500) var staff = svg.append("g").attr("class", "staff") .attr("transform", "translate(50,50)") svg.append("text") .text("Twinkle, twinkle, little star") .attr("y", 450) .attr("x", 120) .style("font-size", 36) .style("font-family", "monospace") function example(){ tones.play(440); // plays a 440 hz tone tones.play("c"); // plays a C note in the 4th octave. tones.play("c#"); // plays a C sharp note in the 4th octave. tones.play("eb"); // plays an E flat note in the 4th octave. tones.play("c", 2); // plays a C note in the 2nd octave. } var note = staff.append("g").attr("class", "note") .attr("transform", "translate(0,0)") var noteBody = note.append("circle") .attr("class", "note body") .attr("r", size) .style("fill", "#000"); var noteStem = note.append("line") .attr("class", "note stem") .attr("x1", size - 1) .attr("x2", size - 1) .attr("y1", 0) .attr("y2", -(4 * size)) .style("stroke", "#000") .style("stroke-width", 2) var noteLedger = note.append("line") .attr("class", "note ledger") .attr("x1", -(2 * size)) .attr("x2", (2 * size)) .attr("y1", 0) .attr("y2", 0) .style("stroke", "#000") .style("stroke-width", 2); var linesAndSpaces = d3.cross( [2, 3, 4, 5], //, 6, 7, 8, 9], ['c', 'd', 'e', 'f', 'g', 'a', 'b'], (a, b) => a + b); var pitchPosition = function(note){ return 4 + note.substring(0, 1); } var pitchs = tones.pitchMap[4] var trebleClef = ['4e', '4f', '4g', '4a', '4b', '5c', '5d', '5e', '5f'], bassClef = ['2g', '2a', '2b', '3c', '3d', '3e', '3f', '3g', '3a'], fullClef = ['4c', '4d', '4e', '4f', '4g', '4a', '4b', '5c', '5d', '5e', '5f']; console.clear() var trebleScale = d3.scaleOrdinal() .range(d3.range(trebleClef.length * size, 0, -size)) .domain(trebleClef) var fullScale = d3.scaleOrdinal() .range(d3.range(fullClef.length * size, 0, -size)) .domain(fullClef) var makeStaff = d3.axisLeft(trebleScale) .tickValues(['4e', '4g', '4b', '5d', '5f']) .tickSize(-850) .tickFormat("") staff.call(makeStaff) var pitch = function(note, octave){ if(octave == null) { octave = 4; } return tones.map[octave][note.toLowerCase()] } function song() { tones.type = "square"; tones.attack = 20; tones.release = 200; var notes = "ccggaag-ffeeddc-ggffeed-ggffeed-ccggaag-ffeeddc----------", timing = 300, index = 0; var prevTime = tones.getTimeMS(); var elapsed = 0 play(); function play() { var now = tones.getTimeMS(); elapsed += now - prevTime; if(elapsed > timing) { elapsed -= timing; var note = notes.charAt(index); if(note !== "-") { tones.play(note); d3.select("g.note").attr("transform", "translate(" + (index * 15 + 100) + "," + fullScale(pitchPosition(note)) + ")") if(fullScale(pitchPosition(note)) >= fullScale(pitchPosition('4c'))){ d3.select(".ledger").style("stroke-width", 2) } else { d3.select(".ledger").style("stroke-width", 0) } } index++; index %= notes.length; } prevTime = now; requestAnimationFrame(play); } } song() </script> </body>
https://d3js.org/d3.v4.min.js