css Audio Visualizer ver2
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了css Audio Visualizer ver2相关的知识,希望对你有一定的参考价值。
Audio Visualizer ver2
---------------------
A [Pen](https://codepen.io/ykob/pen/jbmPxr) by [yoichi kobayashi](https://codepen.io/ykob) on [CodePen](https://codepen.io).
[License](https://codepen.io/ykob/pen/jbmPxr/license).
<canvas id="canvas"></canvas>
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
module.exports = function(object, eventType, callback){
var timer;
object.addEventListener(eventType, function(event) {
clearTimeout(timer);
timer = setTimeout(function(){
callback(event);
}, 500);
}, false);
};
},{}],2:[function(require,module,exports){
var Vector2 = require('./vector2');
var exports = {
friction: function(acceleration, mu, normal, mass) {
var force = acceleration.clone();
if (!normal) normal = 1;
if (!mass) mass = 1;
force.multiplyScalar(-1);
force.normalize();
force.multiplyScalar(mu);
return force;
},
drag: function(acceleration, value) {
var force = acceleration.clone();
force.multiplyScalar(-1);
force.normalize();
force.multiplyScalar(acceleration.length() * value);
return force;
},
hook: function(velocity, anchor, rest_length, k) {
var force = velocity.clone().sub(anchor);
var distance = force.length() - rest_length;
force.normalize();
force.multiplyScalar(-1 * k * distance);
return force;
}
};
module.exports = exports;
},{"./vector2":6}],3:[function(require,module,exports){
var Util = require('./util');
var Vector2 = require('./vector2');
var Force = require('./force');
var debounce = require('./debounce');
var Mover = require('./mover');
var body = document.body;
var body_width = body.clientWidth * 2;
var body_height = body.clientHeight * 2;
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var audio_ctx = new (window.AudioContext || window.webkitAudioContext)();
var audio_analyser = audio_ctx.createAnalyser();
var audio_buffer = new XMLHttpRequest();
//var audio_url = 'https://api.soundcloud.com/tracks/89297698/stream?client_id=0aaf73b4de24ee4e86313e01d458083d';
var audio_url = 'https://api.soundcloud.com/tracks/127070185/stream?client_id=0aaf73b4de24ee4e86313e01d458083d';
var fft_size = 512;
var movers = [];
var last_time_xxx = Date.now();
var vector_touch_start = new Vector2();
var vector_touch_move = new Vector2();
var vector_touch_end = new Vector2();
var is_touched = false;
var init = function() {
poolMover();
initAudio();
resizeCanvas();
renderloop();
debounce(window, 'resize', function(event){
resizeCanvas();
});
};
var initAudio = function() {
audio_analyser.fft_size = fft_size;
audio_analyser.connect(audio_ctx.destination);
loadAudio();
};
var loadAudio = function() {
var request = new XMLHttpRequest();
request.open('GET', audio_url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
audio_ctx.decodeAudioData(request.response, function(buffer) {
audio_buffer = buffer;
playAudio();
});
};
request.send();
};
var playAudio = function() {
var source = audio_ctx.createBufferSource();
source.buffer = audio_buffer;
source.connect(audio_analyser);
source.loop = true;
source.loopStart = 0;
source.loopEnd = audio_buffer.duration;
source.playbackRate.value = 1.0;
source.start(0);
};
var poolMover = function() {
for (var i = 0; i < fft_size; i++) {
var mover = new Mover();
var deg = i / fft_size * 360;
var rad = Util.getRadian(deg);
var x = Math.cos(rad) + body_width / 2;
var y = Math.sin(rad) + body_height / 2;
var position = new Vector2(x, y);
mover.init(position, 20);
mover.h = Math.abs(deg - 180) / 4;
movers.push(mover);
}
};
var updateMover = function() {
var spectrums = new Uint8Array(audio_analyser.frequencyBinCount);
var str = '';
var length = 0;
audio_analyser.getByteTimeDomainData(spectrums);
spectrum_length = audio_analyser.frequencyBinCount;
for (var i = 0; i < movers.length; i++) {
var mover = movers[i];
var rad = Util.getRadian(i / movers.length * 360);
var r = body_height / 3;
var x = Math.cos(rad) * r + body_width / 2;
var y = Math.sin(rad) * r + body_height / 2;
var size = Math.pow(Math.abs(spectrums[i * 2] - 128) / 128 + 1.1, 7);
mover.h += 0.1
mover.radius = size;
mover.velocity.set(x, y);
mover.updateVelocity();
mover.updatePosition();
mover.draw(ctx);
}
};
var render = function() {
ctx.globalCompositeOperation = 'lighter';
ctx.clearRect(0, 0, body_width, body_height);
updateMover();
};
var renderloop = function() {
var now = Date.now();
requestAnimationFrame(renderloop);
render();
// if (now - last_time_xxx > 1000) {
// function_name();
// last_time_xxx = Date.now();
// }
};
var resizeCanvas = function() {
body_width = body.clientWidth * 2;
body_height = body.clientHeight * 2;
canvas.width = body_width;
canvas.height = body_height;
canvas.style.width = body_width / 2 + 'px';
canvas.style.height = body_height / 2 + 'px';
};
init();
},{"./debounce":1,"./force":2,"./mover":4,"./util":5,"./vector2":6}],4:[function(require,module,exports){
var Util = require('./util');
var Vector2 = require('./vector2');
var Force = require('./force');
var exports = function(){
var Mover = function() {
this.position = new Vector2();
this.velocity = new Vector2();
this.acceleration = new Vector2();
this.anchor = new Vector2();
this.radius = 0;
this.mass = 1;
this.direction = 0;
this.h = 0;
this.s = 80;
this.l = 15;
this.a = 0.5;
this.time = 0;
this.is_active = false;
};
Mover.prototype = {
init: function(vector, size) {
this.radius = size;
this.mass = this.radius / 100;
this.position = vector.clone();
this.velocity = vector.clone();
this.anchor = vector.clone();
this.acceleration.set(0, 0);
this.a = 1;
this.time = 0;
},
updatePosition: function() {
this.position.copy(this.velocity);
},
updateVelocity: function() {
this.velocity.add(this.acceleration);
if (this.velocity.distanceTo(this.position) >= 1) {
this.direct(this.velocity);
}
},
applyForce: function(vector) {
this.acceleration.add(vector);
},
applyFriction: function() {
var friction = Force.friction(this.acceleration, 0.1);
this.applyForce(friction);
},
applyDragForce: function(value) {
var drag = Force.drag(this.acceleration, value);
this.applyForce(drag);
},
hook: function(rest_length, k) {
var force = Force.hook(this.velocity, this.anchor, rest_length, k);
this.applyForce(force);
},
direct: function(vector) {
var v = vector.clone().sub(this.position);
this.direction = Math.atan2(v.y, v.x);
},
draw: function(context) {
context.fillStyle = 'hsla(' + this.h + ',' + this.s + '%,' + this.l + '%,' + this.a + ')';
context.beginPath();
context.arc(this.position.x, this.position.y, this.radius, 0, Math.PI / 180, true);
context.fill();
},
activate: function () {
this.is_active = true;
},
inactivate: function () {
this.is_active = false;
}
};
return Mover;
};
module.exports = exports();
},{"./force":2,"./util":5,"./vector2":6}],5:[function(require,module,exports){
var exports = {
getRandomInt: function(min, max){
return Math.floor(Math.random() * (max - min)) + min;
},
getDegree: function(radian) {
return radian / Math.PI * 180;
},
getRadian: function(degrees) {
return degrees * Math.PI / 180;
},
getSpherical: function(rad1, rad2, r) {
var x = Math.cos(rad1) * Math.cos(rad2) * r;
var z = Math.cos(rad1) * Math.sin(rad2) * r;
var y = Math.sin(rad1) * r;
return [x, y, z];
}
};
module.exports = exports;
},{}],6:[function(require,module,exports){
//
// このVector2クラスは、three.jsのTHREE.Vector2クラスの計算式の一部を利用しています。
// https://github.com/mrdoob/three.js/blob/master/src/math/Vector2.js#L367
//
var exports = function(){
var Vector2 = function(x, y) {
this.x = x || 0;
this.y = y || 0;
};
Vector2.prototype = {
set: function (x, y) {
this.x = x;
this.y = y;
return this;
},
clone: function () {
return new Vector2(this.x, this.y);
},
copy: function (v) {
this.x = v.x;
this.y = v.y;
return this;
},
add: function (v) {
this.x += v.x;
this.y += v.y;
return this;
},
addScalar: function (s) {
this.x += s;
this.y += s;
return this;
},
sub: function (v) {
this.x -= v.x;
this.y -= v.y;
return this;
},
subScalar: function (s) {
this.x -= s;
this.y -= s;
return this;
},
multiply: function (v) {
this.x *= v.x;
this.y *= v.y;
return this;
},
multiplyScalar: function (s) {
this.x *= s;
this.y *= s;
return this;
},
divide: function (v) {
this.x /= v.x;
this.y /= v.y;
return this;
},
divideScalar: function (s) {
if (this.x !== 0 && s !== 0) this.x /= s;
if (this.y !== 0 && s !== 0) this.y /= s;
return this;
},
min: function (v) {
if (this.x < v.x) this.x = v.x;
if (this.y < v.y) this.y = v.y;
return this;
},
max: function (v) {
if (this.x > v.x) this.x = v.x;
if (this.y > v.y) this.y = v.y;
return this;
},
clamp: function (v_min, v_max) {
if (this.x < v_min.x) {
this.x = v_min.x;
} else if (this.x > v_max.x) {
this.x = v_max.x;
}
if (this.y < v_min.y) {
this.y = v_min.y;
} else if (this.y > v_max.y) {
this.y = v_max.y;
}
return this;
},
clampScalar: function () {
var min, max;
return function clampScalar(minVal, maxVal) {
if (min === undefined) {
min = new Vector2();
max = new Vector2();
}
min.set(minVal, minVal);
max.set(maxVal, maxVal);
return this.clamp(min, max);
};
}(),
floor: function () {
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
return this;
},
ceil: function () {
this.x = Math.ceil(this.x);
this.y = Math.ceil(this.y);
return this;
},
round: function () {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
},
roundToZero: function () {
this.x = (this.x < 0) ? Math.ceil(this.x) : Math.floor(this.x);
this.y = (this.y < 0) ? Math.ceil(this.y) : Math.floor(this.y);
return this;
},
negate: function () {
this.x = - this.x;
this.y = - this.y;
return this;
},
dot: function (v) {
return this.x * v.x + this.y * v.y;
},
lengthSq: function () {
return this.x * this.x + this.y * this.y;
},
length: function () {
return Math.sqrt(this.lengthSq());
},
lengthManhattan: function() {
return Math.abs(this.x) + Math.abs(this.y);
},
normalize: function () {
return this.divideScalar(this.length());
},
distanceTo: function (v) {
var dx = this.x - v.x;
var dy = this.y - v.y;
return Math.sqrt(dx * dx + dy * dy);
},
distanceToSquared: function (v) {
var dx = this.x - v.x, dy = this.y - v.y;
return dx * dx + dy * dy;
},
setLength: function (l) {
var oldLength = this.length();
if (oldLength !== 0 && l !== oldLength) {
this.multScalar(l / oldLength);
}
return this;
},
lerp: function (v, alpha) {
this.x += (v.x - this.x) * alpha;
this.y += (v.y - this.y) * alpha;
return this;
},
lerpVectors: function (v1, v2, alpha) {
this.subVectors(v2, v1).multiplyScalar(alpha).add(v1);
return this;
},
equals: function (v) {
return ((v.x === this.x) && (v.y === this.y));
},
fromArray: function (array, offset) {
if (offset === undefined) offset = 0;
this.x = array[ offset ];
this.y = array[ offset + 1 ];
return this;
},
toArray: function (array, offset) {
if (array === undefined) array = [];
if (offset === undefined) offset = 0;
array[ offset ] = this.x;
array[ offset + 1 ] = this.y;
return array;
},
fromAttribute: function (attribute, index, offset) {
if (offset === undefined) offset = 0;
index = index * attribute.itemSize + offset;
this.x = attribute.array[ index ];
this.y = attribute.array[ index + 1 ];
return this;
}
}
return Vector2;
};
module.exports = exports();
},{}]},{},[3])
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
height: 100%;
overflow: hidden;
font-family: 'source code pro';
background: radial-gradient(ellipse at center, #000000 44%, #222222 100%);
}
canvas {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
p {
line-height: 1.5;
position: relative;
z-index: 2;
padding: 1em;
color: #00ee00;
word-wrap:break-word;
}
以上是关于css Audio Visualizer ver2的主要内容,如果未能解决你的问题,请参考以下文章
初始化 Visualizer 时的 Android 错误代码 -3