<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>声纳</title>
<script src="js/jquery.min.js"></script>
<style>
body {
margin: 0;
}
#mainCanvas {
display: block;
}
.legend {
pointer-events: none;
position: absolute;
color: white;
font-family: sans-serif;
}
.legend p {
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
/* Rules below not implemented in browsers yet */
-o-user-select: none;
user-select: none;
top: 10px;
left: 25px;
position: relative;
margin: 0;
text-transform: uppercase;
letter-spacing: 5px;
}
.legend p.vert {
left: 5px;
margin-top: 10px;
writing-mode: vertical-lr;
text-orientation: upright;
}
</style>
</head>
<body>
<script src="js/Pizzicato.min.js"></script>
<div class="legend">
<p class="">Pitch</p>
<p class="vert">Volume</p>
</div>
<canvas id="mainCanvas" background="#FFFFFF">Canvas fail!</canvas><script>
var SceneManager = function(ctx){
this.waves = [];
this.hue = 208;
this.sat = 64;
this.lum = 15;
this.opacity = 1;
this.msgOpacity = 1;
this.started = false;
//button handlers
this.mouseOff = function(){
}
this.mouseHover = function(mouse){
}
this.mouseClick = function(mouse){
this.started = true;
this.createWave(mouse.x, mouse.y)
}
this.createWave = function(centerX, centerY){
var wave = new Wave(ctx, centerX, centerY);
wave.init();
this.waves.push(wave);
}
this.destroyWave = function(index){
this.waves.splice(index, 1);
}
this.update = function(){
if(this.started){
this.msgOpacity -= 0.05;
}
for(var i = 0; i < this.waves.length; i++){
this.waves[i].update();
if(this.waves[i].ripples.length === 0){
this.destroyWave(this.waves[i]);
}
}
}
this.render = function(){
ctx.beginPath();
ctx.lineWidth = 1;
ctx.textAlign="start";
ctx.fillStyle = "hsla("+this.hue+", "+this.sat+"%, "+this.lum+"%, "+this.opacity+")";
ctx.fillRect(0,0,canvasWidth, canvasHeight);
ctx.strokeStyle = "hsla(255, 255%, 255%, 1)";
ctx.moveTo(5, 25);
ctx.lineTo(250, 25);
ctx.moveTo(20, 5);
ctx.lineTo(20, 250);
ctx.font = "15px Arial";
ctx.strokeText('+', 240, 20);
ctx.strokeText('+', 5, 240);
ctx.font = "32px Arial";
ctx.textAlign="center";
ctx.fillStyle= "hsla(255, 255%, 255%,"+ this.msgOpacity+ " )";
ctx.fillText('Click anywhere to make some noise', canvasWidth/2, canvasHeight/2);
ctx.stroke();
ctx.closePath();
for(var i = 0; i < this.waves.length; i++){
this.waves[i].render();
}
}
}
var Wave = function(ctx, cx, cy){
this.ripples = [];
this.rippleSpeed = 10;
this.rippleCount = 4;
this.init = function(){
for(var i = 1; i < this.rippleCount+1; i++){
var decay = Math.pow(0.65, i);
var ripple = new Ripple(ctx, cx, cy, this.rippleSpeed, decay);
ripple.init();
this.ripples.push(ripple);
}
this.ripples[0].sound.play();
}
this.destroyRipple = function(index){
this.ripples.splice(index, 1);
}
this.update = function() {
for(var i = 0; i < this.ripples.length; i++){
this.ripples[i].update();
if(this.ripples[i].killMe){
this.destroyRipple(i);
}
}
}
this.render = function() {
for(var i = 0; i < this.ripples.length; i++){
this.ripples[i].render();
}
}
}
var Ripple = function(ctx, cx, cy, r, decay){
this.radius = 1;
this.shadowRadius = 0;
this.rSpeed = r;
this.decay = decay;
this.lineWidth = 10;
this.epicenterX = cx;
this.epicenterY = cy;
this.sound;
this.killMe = false;
this.opacity = 1;
this.init = function() {
this.createSound();
}
this.createSound = function(){
this.sound = new Pizzicato.Sound({
source: 'wave',
options: {
volume: this.epicenterY/canvasHeight,
frequency: this.epicenterX
}
});
var delay = new Pizzicato.Effects.DubDelay({
feedback: 0.5,
time: 0.7,
mix: 0.5,
cutoff: 500
});
this.sound.addEffect(delay);
}
this.update = function(){
this.rDelta = this.rSpeed*this.decay;
this.radius+= this.rDelta;
this.shadowRadius+= this.rDelta;
if(this.radius > 100){
this.sound.stop();
}
if(this.lineWidth > 1){
this.lineWidth -= 0.35*this.decay;
}
if(this.radius > 250 && this.opacity > 0){
this.opacity -= 0.1;
}
//this.build();
if(this.radius > 400){
this.killMe = true;
}
}
this.render = function(){
ctx.beginPath();
ctx.lineWidth = this.lineWidth+2;
ctx.strokeStyle = "hsla(33, 97%, 49%, "+this.opacity+")";
ctx.arc(this.epicenterX,this.epicenterY,this.shadowRadius,0,2*Math.PI);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = "hsla(255, 255%, 255%, "+this.opacity+")";
ctx.arc(this.epicenterX,this.epicenterY,this.radius,0,2*Math.PI);
ctx.stroke();
ctx.closePath();
}
}
// LIFECYCLE
var frames = 0;
function update() {
frames++;
sm.update();
// render
render();
}
function render() {
// clear
context.clearRect(0, 0, canvasWidth, canvasHeight);
sm.render();
requestAnimationFrame(update);
}
// DEFINITIONS
var canvas = document.getElementById('mainCanvas');
var context = canvas.getContext('2d');
var canvasWidth = canvas.width = window.innerWidth;
var canvasHeight = canvas.height = window.innerHeight;
var currentFrame = 0;
var mouseX = -1;
var mouseY = -1;
var isMousePressed = false;
var sm = new SceneManager(context);
window.onresize = function(){
canvasWidth = canvas.width = window.innerWidth;
canvasHeight = canvas.height = window.innerHeight;
}
function onMouseMove(evt) {
mouseX = evt.clientX;
mouseY = evt.clientY;
}
function onMouseDown(evt) {
isMousePressed = true;
}
function onMouseUp(evt) {
isMousePressed = false;
sm.mouseClick(evt);
}
canvas.addEventListener("mousemove", onMouseMove);
canvas.addEventListener("mousedown", onMouseDown);
canvas.addEventListener("mouseup", onMouseUp);
requestAnimationFrame(update);
</script>
</body>
</html>