-
Notifications
You must be signed in to change notification settings - Fork 641
/
WhitneyMusicBox.html
122 lines (118 loc) · 3.94 KB
/
WhitneyMusicBox.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<!DOCTYPE html>
<html lang="en">
<head>
<title>Whitney Music Box in HTML5</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<!-- shim -->
<script src="../inc/shim/Base64.js" type="text/javascript"></script>
<script src="../inc/shim/Base64binary.js" type="text/javascript"></script>
<script src="../inc/shim/WebAudioAPI.js" type="text/javascript"></script>
<!-- midi.js package -->
<script src="../js/midi/audioDetect.js" type="text/javascript"></script>
<script src="../js/midi/gm.js" type="text/javascript"></script>
<script src="../js/midi/loader.js" type="text/javascript"></script>
<script src="../js/midi/plugin.audiotag.js" type="text/javascript"></script>
<script src="../js/midi/plugin.webaudio.js" type="text/javascript"></script>
<script src="../js/midi/plugin.webmidi.js" type="text/javascript"></script>
<script src="../js/midi/player.js" type="text/javascript"></script>
<!-- utils -->
<script src="../js/util/dom_request_xhr.js" type="text/javascript"></script>
<script src="../js/util/dom_request_script.js" type="text/javascript"></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 () {
MIDI.loader = new sketch.ui.Timer;
MIDI.loadPlugin({
soundfontUrl: "./soundfont/",
instrument: "acoustic_grand_piano", // or multiple instruments
onprogress: function(state, progress) {
MIDI.loader.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>