js通過audioContext實現(xiàn)3D音效
更新時間:2021年04月19日 11:09:08 作者:莫兮是我
這篇文章主要為大家詳細介紹了js通過audioContext實現(xiàn)3D音效,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了js通過audioContext實現(xiàn)3D音效的具體代碼,供大家參考,具體內(nèi)容如下
前言
AudioContext的setPosition實現(xiàn)3D音效
效果展示

代碼展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>3D Audio</title>
<style>
body, div{
margin: 0px;
padding: 0px;
text-align: center;
}
#cav{
border: 1px solid black;
border-radius: 4px;
margin: 10px auto;
}
</style>
</head>
<body>
<canvas id="cav" width="320" height="200"></canvas>
</body>
<script>
let Aud = function (ctx, url) {
this.ctx = ctx;
this.url = url;
// source節(jié)點
this.src = ctx.createBufferSource();
// 多個處理節(jié)點組
this.pNode = [];
};
Aud.prototype = {
output(){
for (let i = 0; i < this.pNode.length; i++){
let tNode = this.src;
for (let j = 0; j < this.pNode[i].length; j++){
tNode.connect(this.pNode[i][j]);
tNode = this.pNode[i][j];
}
tNode.connect(this.ctx.destination);
}
},
play(loop){
this.src.loop = loop || false;
this.output();
this.src.start(0);
},
stop() {
this.src.stop();
},
addNode(node, groupIdx = 0){
this.pNode[groupIdx] = this.pNode[groupIdx] || [];
this.pNode[groupIdx].push(node);
}
};
//設(shè)置節(jié)點類型
Aud.NODETYPE = {
GNODE: 0 // 表示gainNode節(jié)點
}
//Aud管理對象
AudManager = {
urls: [],
items: [],
ctx: null,
init(){
try{
this.ctx = new AudioContext();
}catch (e) {
console.log(`${e}`);
}
},
load(callback){
for (let i = 0; i < this.urls.length; i++){
this.loadSingle(this.urls[i], callback);
}
},
loadSingle(url, callback){
let req = new XMLHttpRequest();
req.open('GET', url, true);
req.responseType = 'arraybuffer';
let self = this;
req.onload = function () {
self.ctx.decodeAudioData(this.response)
.then(
buf => {
let aud = new Aud(self.ctx, url);
aud.src.buffer = buf;
self.items.push(aud);
if (self.items.length == self.urls.length){
callback();
}
},
err => {
console.log(`decode error:${err}`);
}
)
};
req.send();
},
createNode(nodeType, param){
let node = null;
switch (nodeType) {
case 1:
node = this.ctx.createPanner();
break;
case 2:
node = this.ctx.createScriptProcessor(param[0], param[1], param[2]);
break;
default:
node = this.ctx.createGain();
}
return node;
}
};
let ctx = document.getElementById('cav').getContext('2d');
// 定義移動點坐標
let cX = 190,
cY = 100,
deg = 0;
window.onload = function (){
init();
}
function renderCir(x, y, r, col){
ctx.save();
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2);
ctx.closePath();
ctx.fillStyle = col;
ctx.fill();
ctx.restore();
}
function renderCenter(){
renderCir(160, 100, 8, "red");
}
function renderCat() {
renderCir(cX, cY, 8, "blue");
}
function init(){
AudManager.urls = ["test.mp3"];
AudManager.init();
AudManager.load(()=>{
let pNod1 = AudManager.createNode(1);
let sound1 = AudManager.items[0];
sound1.addNode(pNod1);
sound1.play(true);
timeHandle();
});
}
function timeHandle() {
window.setInterval(()=>{
ctx.clearRect(0,0,320,200);
let rad = Math.PI*deg / 180;
let sx = 90*Math.cos(rad),
sy = 90*Math.sin(rad);
cX = 160 + sx;
cY = 100 + sy;
AudManager.items[0].pNode[0][0].setPosition(sx*0.1, -sy*0.1, 0);
renderCenter();
renderCat();
deg++;
}, 30);
}
</script>
</html>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
如何設(shè)置iframe高度自適應(yīng)在跨域情況下的可用方法
iframe的高度需要根據(jù)子頁面的實際高度來進行調(diào)整,但是如果子頁面不在同一域中怎么辦?這時候腳本沒有辦法獲取到子頁面的高度,存在JavaScript跨域的問題2013-09-09
你必須知道的Javascript知識點之"深入理解作用域鏈"的介紹
本篇文章小編為大家介紹,你必須知道的Javascript知識點之"深入理解作用域鏈"的介紹。需要的朋友參考下2013-04-04
解決layui數(shù)據(jù)表格排序圖標被超出的表頭擠出去的問題
今天小編就為大家分享一篇解決layui數(shù)據(jù)表格排序圖標被超出的表頭擠出去的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
Javascript將雙字節(jié)字符轉(zhuǎn)換成單字節(jié)字符并計算長度
這篇文章主要介紹Javascript將雙字節(jié)字符轉(zhuǎn)換成單字節(jié)字符并計算長度的方法,簡單實用,需要的朋友可以參考下。2016-06-06
webpack學(xué)習(xí)教程之前端性能優(yōu)化總結(jié)
webpack是近期最火的一款模塊加載器兼打包工具,它能把各種資源,例如JS(含JSX)、coffee、樣式(含less/sass)、圖片等都作為模塊來使用和處理。這篇文章主要給大家總結(jié)介紹了關(guān)于webpack學(xué)習(xí)教程之前端性能優(yōu)化的相關(guān)資料,需要的朋友可以參考下。2017-12-12

