<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>声纳</title>
<script src="https://cdn.bootcss.com/jquery/3.2.1/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="https://cdn.bootcss.com/pizzicato/0.6.1/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('点击任何地方发出一些噪音', 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>
canvas 实现声呐发声效果
最新推荐文章于 2024-05-13 09:42:20 发布