为了账号安全,请及时绑定邮箱和手机立即绑定

交作业啦!

/*
 * /rutes/index.js
 */

var express = require('express');
var router = express.Router();
var path = require('path');
var media = path.join(__dirname, "../public/media/");

/* GET home page. */
router.get('/', function(req, res, next) {
	var fs = require('fs');
	fs.readdir(media, function(err, names){
		if (err) {
			console.log(err);
		} else{
			res.render('index', { title: 'Passionate Music', music: names });
		};
	})
});

module.exports = router;
<!--
- /views/index.ejs
-->

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  	<header>
  		<h1><%= title %></h1>
  		<ul class="type" id="type">
  			<li data-type="dot">Dot</li>
  			<li data-type="column" class="selected">Column</li>
  		</ul>
  		<p>
  			<label>Volume <input id="volume" type="range" name="" value="60" min="0" max="100"></label>
  		</p>
  	</header>
  	<div class="left">
  		<ul id="list">
  			<% music.forEach(function (name) { %>
  				<li title="<%= name %>"><%= name %></li>
  			<% }) %>
  		</ul>
  	</div>
  	<div class="right" id="box"></div>
  	<script src="/javascripts/musicVisualizer.js"></script>
  	<script src="/javascripts/index.js"></script>
  </body>
</html>
/*
 * /public/javascript/index.js
 */

function $ (s) {
	return document.querySelectorAll(s);
};

var lis = $('#list li');
var size = 32;
var box = $("#box")[0];
var width, height;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
	box.appendChild(canvas);
var dots = [];
var linear;

var mv = new musicVisualizer({
	size: size,
	visualizer: draw
});

for (var i = 0; i < lis.length; i++) {
	lis[i].onclick = function (argument) {
		for (var j = 0; j < lis.length; j++) {
			lis[j].className = "";
		};
		this.className = "selected";
		mv.play("../media/" + this.title);

		};
};

function random (m, n) {
	return Math.round(Math.random() * (n - m) + m);
}

function getDots () {
	dots = [];
	
	for (var i = 0; i < size; i++) {
		var x = random(0, width);
		var y = random(0, height);
		var color = "rgba(" + random(0, 255) + "," + random(0, 255) + "," + random(0, 255) + ", 0)";
		dots.push({
			x: x,
			y: y,
			dx: random(1, 2),
			color: color,
			cap: 0
		});
	};	
};

function resize () {
	height = box.clientHeight;
	width = box.clientWidth;
	canvas.height = height;
	canvas.width = width;

	linear = ctx.createLinearGradient(0, 0, 0, height);
	linear.addColorStop(0, "red");
	linear.addColorStop(0.5, "yellow");
	linear.addColorStop(1, "green");

	getDots();
};

resize();

function draw (arr) {
	var w = width / size;
	var cw = w * 0.6;
	var capHeight = cw > 10 ? 10 : cw;
	
	ctx.fillStyle = linear;
	ctx.clearRect(0, 0, width, height)

	for (var i = 0; i < size; i++) {
		var o = dots[i];

		if(draw.type == "column"){
			var h = arr[i] / 256 * height;
			ctx.fillRect(w * i, height - h, cw, h);
			ctx.fillRect(w * i, height - (o.cap + capHeight), cw, capHeight);
			o.cap --;

			if(o.cap < 0){
				o.cap = 0;	
			};

			if(h > 0 && o.cap < h + 40){
				o.cap = h + 40 > height - capHeight ? height - capHeight : h + 40;
			};
		}
		else if(draw.type == "dot"){
			ctx.beginPath();

			var r = 10 + arr[i] / 256 * (height > width ? width : height) / 10;
			ctx.arc(o.x, o.y, r, 0, Math.PI * 2, true);

			var g = ctx.createRadialGradient(o.x, o.y, 0, o.x, o.y, r);
			g.addColorStop(0, "#fff");
			g.addColorStop(1, o.color);

			ctx.fillStyle = g;
			ctx.fill();

			o.x += o.dx;
			o.x = o.x > width ? 0 : o.x;
		};
	};
};

draw.type = "column";

var type = $("#type li");
for (var i = 0; i < type.length; i++) {
	type[i].onclick = function () {
		for (var j = 0; j < type.length; j++) {
			type[j].className = "";
		};
		this.className = "selected";
		draw.type = this.getAttribute("data-type");
	};
};

window.onresize = resize;

$("#volume")[0].onchange = function (argument) {
	mv.changeVolume(this.value / this.max);
};

$("#volume")[0].onchange();
/*
 * /public/javascript/musicVisualizer.js
 */

function musicVisualizer (obj) {
	this.source = null;

	this.count = 0;

	this.analyser = musicVisualizer.ac.createAnalyser();
	this.size = obj.size;
	this.analyser.fftSize = this.size * 2;

	this.gainNode = musicVisualizer.ac[musicVisualizer.ac.createGain ? "createGain" : "createGainNode"]();
	this.gainNode.connect(musicVisualizer.ac.destination);

	this.analyser.connect(this.gainNode);

	this.xhr = new XMLHttpRequest();

	this.visualizer = obj.visualizer;

	this.visualize();
};

musicVisualizer.ac = new ( window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext || window.AudioContext)();

musicVisualizer.prototype.load = function (url, fn) {
	this.xhr.abort();
	this.xhr.open("GET", url);
	this.xhr.responseType = "arraybuffer";
	
	var self = this;
	this.xhr.onload = function () {
		fn(self.xhr.response);
	};

	this.xhr.send();
};

musicVisualizer.prototype.decode = function (arraybuffer, fn) {
	musicVisualizer.ac.decodeAudioData(arraybuffer, function (buffer) {
		fn(buffer);
	},
	function (err) {
		console.log(err);
	});	
};

musicVisualizer.prototype.play = function (url) {
	var n = ++this.count;
	var self = this;

	this.source && this.stop();
	this.load(url, function (arraybuffer) {

		if(n != self.count) return;

		self.decode(arraybuffer, function (buffer) {
	
			if(n != self.count) return;

			var bs = musicVisualizer.ac.createBufferSource();
			
			bs.connect(self.analyser);
			bs.buffer = buffer;
			bs[bs.start ? "start" : "noteOn"](0);
			self.source = bs;
		});
	});
};

musicVisualizer.prototype.stop = function (argument) {
	this.source[this.source.stop ? "stop" : "noteOff"](0);	
};

musicVisualizer.prototype.changeVolume = function (percent) {
	this.gainNode.gain.value = percent * percent;
};

musicVisualizer.prototype.visualize = function (argument) {
	var arr = new Uint8Array(this.analyser.frequencyBinCount);

	requestAnimationFrame = window.webkkitRequestAnimationFrame ||
							window.mozRequestAnimationFrame 	||
							window.msRequestAnimationFrame 		||
							window.oRequestAnimationFrame 		||
							window.requestAnimationFrame;

	var self = this;
	function v () {
		self.analyser.getByteFrequencyData(arr);
		self.visualizer(arr);
		requestAnimationFrame(v);
		// console.log(arr);
	};

	requestAnimationFrame(v);

};
/*
 * /public/stylesheets/sytle.css
 */

* {
	padding: 0;
	margin: 0;
	box-sizing: border-box;
}
html,
body {
	height: 100%;
}
body {
	font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
	background-color: #000;
	text-align: center;
}
header,
.left,
.right {
	position: absolute;
}
header {
	color: white;
	height: 150px;
	top: 10px;
	right: 10px;
	left: 10px;
	/*border: 1px #fff solid;*/
}
header h1 {
	font-size: 40px;
	height: 60px;
	line-height: 60px;
}
header .type {
	list-style: none;
	display: inline-block;
	border-radius: 4px;
	border: 1px #ccc solid;
	margin-bottom: 10px;
}
header .type li {
	cursor: pointer;
	float: left;
	font-size: .75rem;
	width: 80px;
	height: 24px;
	line-height: 24px;
	text-align: center;
}
header .type .selected {
	background-color: white;
	color: black;
}
header .type:after {
	content: "";
	clear: both;
	visibility: hidden;
}
.left {
	left: 10px;
	top: 170px;
	bottom: 10px;
	/*width: 200px;*/
	width: 15%;
	/*min-width: 140px;*/
	border: 1px #fff solid;
}
.left ul {
	overflow: auto;
}
.left ul li {
	font-size: .75rem;
	color: white;
	height: 30px;
	line-height: 30px;
	text-align: left;
	padding: 5px;
	cursor: pointer;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}
.left ul .selected {
	color: green;
}
.right {
	top: 170px;
	right: 10px;
	bottom: 10px;
	/*left: 220px;*/
	left: calc(15% + 20px);
	left: -webkit-calc(15% + 20px);
	/*border: 1px #fff solid;*/
}

input[type="range"] { /*滑条*/
	-webkit-appearance = none;	/*取消默认样式*/
	height: 8px;
	background: #999;
	border-radius: 10px;
	outline: none;
}
input[type="range"]::-webkit-slider-thumb {	/*滑块*/
	-webkit-appearance = none;
	height: 12px;
	width: 12px;
	background: #fff;
	border-radius: 100%;
}
input[type="range"]::-moz-range-track {	/*滑条*/
	height: 8px;
	background: #999;
	border-radius: 10px;
	border: none;
}
input[type="range"]::-moz-range-thumb {	/*滑块伪类*/
	-webkit-appearance = none;
	height: 12px;
	width: 12px;
	background: #fff;
	border-radius: 100%;
}
@media screen and (max-width: 800px), screen and (max-height: 500px) {
	body {
		font-size: 12px;
	}
	header {
		height: 80px;
	}
	header h1 {
		font-size: 24px;
		height: 34px;
		line-height: 34px;
	}
	header .type {
		margin-bottom: 0;
	}
	header .type li {
		width: 50px;
		height: 16px;
		line-height: 16px;
	}
	.left,
	.right {
		top: 100px;
	}
}


正在回答

1 回答

well done ^ _ ^ 代码中适当加些注释好点,虽然视频中讲课时我没加,那是节约时间哈哈哈哈

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
HTML5音乐可视化
  • 参与学习       76715    人
  • 解答问题       121    个

利用webAudio和canvas可视化你的音乐,让你的音乐动起来

进入课程

交作业啦!

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信