UNPKG

music21j-port

Version:

A toolkit for computer-aided musicology, Javascript version

110 lines (105 loc) 3.17 kB
<!DOCTYPE html> <html lang="en"> <head> <title>Whitney Music Box in HTML5</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <!-- midi.js package --> <script src="../build/midicube.js"></script> <!-- includes --> <script src="./inc/timer.js" type="text/javascript"></script> <!-- font --> <link href="http://fonts.googleapis.com/css?family=Andada" rel="stylesheet" type="text/css" /> <style> body { background: #000; color: #fff; font-family: andada; line-height: 1.5em; } a { color: #fff } </style> </head> <body> Whitney Music Box animation in HTML5.<br> Graphics code by <a href="https://github.com/jbum/Whitney-Music-Box-Examples">Jim Bumgardner</a>.<br> Audio created with <a href="https://github.com/mudcube/MIDI.js">MIDI.js</a><br> <canvas id="mycanvas" /> <script type="text/javascript"> var dc; var nbrPoints = 48; var cycleLength = 60 * 3; // 3 minutes var gw = 800; var gh = 800; var cx = gw / 2; var cy = gh / 2; var circleRadius = (gw / 2) * 0.95; var startTime = (new Date()).getTime(); var PI = 3.1415927; var PI2 = PI * 2; var tines = []; var lastSound = []; RefreshFrame = function () { dc.clearRect(0, 0, gw, gh); dc.lineWidth = 3; dc.strokeStyle = '#333'; dc.beginPath(); dc.moveTo(cx, cy); dc.lineTo(gw, cy); dc.stroke(); var speed = (2 * PI * nbrPoints) / cycleLength; var ms = (new Date()).getTime(); var timer = (ms - startTime) * .001 * speed; var maxRad = (gw / 2 - circleRadius) * .75; var minRad = maxRad * .2; for (var i = 0; i < nbrPoints; ++i) { var r = (i + 1) / nbrPoints; var a = timer * r; var len = circleRadius * (1 + 1.0 / nbrPoints - r); if (Math.floor(a / PI2) !== Math.floor(tines[i] / PI2)) { MIDI.noteOn(0, i + 21, 100, 0); MIDI.noteOn(0, i + 21 + 36, 100, 0); MIDI.noteOff(0, i + 21, 0.1); MIDI.noteOff(0, i + 21 + 36, 0.1); lastSound[i] = ms; } var x = (cx + Math.cos(a) * len); var y = (cy + Math.sin(a) * len); var radv = minRad + (maxRad - minRad) * (1 - r); radv = Math.max((radv + 6) - 6 * (ms - lastSound[i]) / 500.0, radv); var huev = r * 360; var satv = Math.round(100 * Math.min(1, (ms - lastSound[i]) / 1000.0)); var lumv = Math.round(100 * Math.max(0.5, 1 - (ms - lastSound[i]) / 1000.0)); dc.fillStyle = 'hsla(' + huev + ',' + satv + '%,' + lumv + '%,1)'; dc.beginPath(); dc.arc(x, y, radv, 0, PI2, false); dc.fill(); tines[i] = a; } }; window.onload = function () { SketchTimer = new sketch.ui.Timer; MIDI.loadPlugin({ soundfontUrl: "./soundfont/", instrument: "acoustic_grand_piano", // or multiple instruments onprogress: function(state, progress) { SketchTimer.setValue(progress * 100); }, onsuccess: function() { var canvas = document.getElementById('mycanvas'); canvas.style.width = gw + "px"; canvas.style.height = gh + "px"; canvas.width = gw; canvas.height = gh; dc = canvas.getContext('2d'); for (var i = 0; i < nbrPoints; ++i) { if (i % 7 === 0) MIDI.noteOn(0, i + 21, 100, 0); lastSound[i] = 0; tines[i] = 0; } startTime = (new Date()).getTime(); setInterval(RefreshFrame, 1000 / 30); } }); }; </script> </body> </html>