js通過(guò)audioContext實(shí)現(xiàn)3D音效
本文實(shí)例為大家分享了js通過(guò)audioContext實(shí)現(xiàn)3D音效的具體代碼,供大家參考,具體內(nèi)容如下
前言
AudioContext的setPosition實(shí)現(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é)點(diǎn)
this.src = ctx.createBufferSource();
// 多個(gè)處理節(jié)點(diǎn)組
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é)點(diǎn)類型
Aud.NODETYPE = {
GNODE: 0 // 表示gainNode節(jié)點(diǎn)
}
//Aud管理對(duì)象
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');
// 定義移動(dòng)點(diǎn)坐標(biāo)
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>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js實(shí)現(xiàn)遮罩層劃出效果是生成div而不是顯示
單純的遮蓋層劃出是比較簡(jiǎn)單的,而本例介紹的這個(gè)就有點(diǎn)難度,生成div,而不是顯示存在的div,需要的朋友可以參考下2014-07-07
layer頁(yè)面跳轉(zhuǎn),獲取html子節(jié)點(diǎn)元素的值方法
今天小編就為大家分享一篇layer頁(yè)面跳轉(zhuǎn),獲取html子節(jié)點(diǎn)元素的值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09
微信小程序?qū)崿F(xiàn)動(dòng)態(tài)列表項(xiàng)的順序加載動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)動(dòng)態(tài)列表項(xiàng)的順序加載動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
JavaScript數(shù)組實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)中的隊(duì)列與堆棧
這篇文章主要介紹了JavaScript數(shù)組實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)中的隊(duì)列與堆棧的相關(guān)資料,需要的朋友可以參考下2016-05-05
Javascript 更新 JavaScript 數(shù)組的 uniq 方法
2008-01-01
JavaScript學(xué)習(xí)總結(jié)之JS、AJAX應(yīng)用
這篇文章主要介紹了JavaScript學(xué)習(xí)總結(jié)JS AJAX應(yīng)用 的相關(guān)資料,需要的朋友可以參考下2016-01-01
基于JavaScript實(shí)現(xiàn)猜數(shù)字游戲代碼實(shí)例
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)猜數(shù)字游戲代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
webpack 如何同時(shí)輸出壓縮和未壓縮的文件的實(shí)現(xiàn)步驟
這篇文章主要介紹了webpack 如何同時(shí)輸出壓縮和未壓縮的文件的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
簡(jiǎn)單實(shí)現(xiàn)js倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了js倒計(jì)時(shí)效果的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02

