JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<html>
<head>
<title>Touch test</title>
<meta name="viewport" content="user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
</head>
<body ontouchstart="">
<canvas id="content"></canvas>
<ul class="toolbar">
<li><a href="#sparkler">Sparkler</a></li>
<li><a href="#circle">Circle</a></li>
<li><a href="#notes">Notes</a></li>
</ul>
</body>
</html>
CSS
html, body {
background-color: black;
width: 100%;
height: 100%;
margin: 0;
}
canvas {
display: block;
margin: 0;
padding: 0;
position: absolute;
left: 0;
top: 0;
z-index: 0;
}
a, a:visited {
text-decoration: none;
color: white;
}
ul.toolbar {
color: white;
margin: 0 auto;
padding: 0;
list-style: none;
font-size: 1em;
text-align: center;
position: absolute;
left: 0;
top: 0;
z-index: 10;
width: 100%;
}
ul.toolbar li {
display: inline-block;
}
ul.toolbar li a {
display: block;
margin: 0 .5em;
background-color: #333333;
padding: 1em;
}
ul.toolbar li a.selected {
background-color: green;
}
JavaScript
// *** WARNING ***
//
// The code below is incredibly bad. It was hacked on quickly and code
// only for the specific use-cases I wanted to play around with. I may
// clean it up eventually so it's helpful for other people.
var requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
var numParticles = 25;
var ctx;
var canvas;
var audioCtx = null;
var soundBuffer = null;
var particles = [];
var particleImg;
var effect;
function playSound(x, y, quick) {
if(soundBuffer) {
var sound = audioCtx.createBufferSource();
var gain = audioCtx.createGainNode();
sound.buffer = soundBuffer;
sound.playbackRate.value = x/canvas.width*2;
sound.connect(gain);
gain.connect(audioCtx.destination);
var volume = y/canvas.height/4;
gain.gain.value = volume;
if(quick) {
sound.noteGrainOn(0., .2, .4);
}
else {
sound.noteOn(0);
}
}
}
function Note() {
if(audioCtx) {
this.node = audioCtx.createJavaScriptNode(1024, 1, 1);
this.incr = 0;
this.gain = audioCtx.createGainNode();
this.node.connect(this.gain);
}
}
Note.prototype.setFrequency = function(x, y) {
if(audioCtx) {
var freq = x / canvas.width * 2000 + 100;
this.incr = 2 * Math.PI * freq/audioCtx.sampleRate;
var volume = y / canvas.height / 4;
this.gain.gain.value = volume;
}
};
Note.prototype.playNote = function() {
if(this.playing) {
this.stopNote();
}
if(audioCtx) {
var x = 0;
var _this = this;
this.node.onaudioprocess = function(e) {
var data =...