javascript - 如何使用网络音频 API/javascript 操作 DOM?

标签 javascript jquery html api audio

我是编程新手,正在摆弄 Web Audio API。现在,我有三个样本(踢、拍手、踩镲),当按下“播放”按钮时,它们会组成一个简单的鼓组节拍。

我希望能够在前端直观地说明这一点,作为通过该鼓组演奏的音序器。例如,每次播放“kick.wav”样本时,我想更改与其关联的 div 的颜色。

我的问题是:

  1. 如何将每次踢腿、拍手或踩镲演奏与 html 中的 div 关联起来?
  2. 如何在按下播放按钮时将此关联添加到序列中?

HTML:

<body>
  <div id="container">
    <canvas id="canvas"></canvas>
  </div>
    <button id="play">play</button>

    <script src="javascript/tween.js"></script>
    <script src="javascript/shared.js"></script>
    <script src="javascript/seq.js"></script>

</body>

Javascript:

function playSound(buffer, time) {
  var source = context.createBufferSource();
  source.buffer = buffer;
  source.connect(context.destination);
  source.start(time);
}

function loadSounds(obj, soundMap, callback) {
  // Array-ify
  var names = [];
  var paths = [];
  for (var name in soundMap) {
    var path = soundMap[name];
    names.push(name);
    paths.push(path);
  }
  bufferLoader = new BufferLoader(context, paths, function(bufferList) {
    for (var i = 0; i < bufferList.length; i++) {
      var buffer = bufferList[i];
      var name = names[i];
      obj[name] = buffer;
    }
    if (callback) {
      callback();
    }
  });
  bufferLoader.load();
}

function BufferLoader(context, urlList, callback) {
  this.context = context;
  this.urlList = urlList;
  this.onload = callback;
  this.bufferList = new Array();
  this.loadCount = 0;
}

BufferLoader.prototype.loadBuffer = function(url, index) {
  // Load buffer asynchronously
  var request = new XMLHttpRequest();
  request.open("GET", url, true);
  request.responseType = "arraybuffer";

  var loader = this;

  request.onload = function() {
    // Asynchronously decode the audio file data in request.response
    loader.context.decodeAudioData(
      request.response,
      function(buffer) {
        if (!buffer) {
          alert('error decoding file data: ' + url);
          return;
        }
        loader.bufferList[index] = buffer;
        if (++loader.loadCount == loader.urlList.length)
          loader.onload(loader.bufferList);
      },
      function(error) {
        console.error('decodeAudioData error', error);
      }
    );
  }

  request.onerror = function() {
    alert('BufferLoader: XHR error');
  }

  request.send();
};

BufferLoader.prototype.load = function() {
  for (var i = 0; i < this.urlList.length; ++i)
  this.loadBuffer(this.urlList[i], i);
};

var RhythmSample = function() {
  loadSounds(this, {
    kick: 'sounds/kick.wav',
    claps: 'sounds/claps.wav',
    hihat: 'sounds/hihat.wav'
  });
};

RhythmSample.prototype.play = function() {
  // We'll start playing the rhythm 100 milliseconds from "now"
  var startTime = context.currentTime + 0.100;
  var tempo = 120; // BPM (beats per minute)
  var eighthNoteTime = (60 / tempo) / 2;
  var allDivs = document.getElementsByName('colorchangingdivs[]');

  // Play 2 bars of the following:
  for (var bar = 0; bar < 2; bar++) {
    var time = startTime + bar * 8 * eighthNoteTime;
    // Play the bass (kick) drum on beats 1, 5
    playSound(this.kick, time);

    playSound(this.kick, time + 4 * eighthNoteTime);
    console.log("4")
    // Play the snare drum on beats 3, 7
    playSound(this.claps, time + 2 * eighthNoteTime);
    playSound(this.claps, time + 6 * eighthNoteTime);

    // Play the hi-hat every eighthh note.
    for (var i = 0; i < 8; ++i) {
      playSound(this.hihat, time + i * eighthNoteTime);
    }
  }
};

var sample = new RhythmSample();

document.querySelector('#play').addEventListener('click', function() {
  sample.play();
});

非常感谢!

最佳答案

向 playSound() 添加另一个参数,该参数与您要着色的 div id 相匹配。以及在播放声音时更改颜色的逻辑,通过您传入的 id 选择 div。

function playSound(buffer, time, colorID) {
  var source = context.createBufferSource();
  source.buffer = buffer;
  source.connect(context.destination);
  source.start(time);
  document.getElementById(colorID).backgroundColor = blue; //or hex color/rgb value
}

然后您只需在调用 playSound 时添加正确的参数即可。

playSound(this.kick, time + 4 * eighthNoteTime,"your-kick-div-id");

如果您需要为不同的声音/div使用不同的颜色,那么只需在背景颜色设置中添加 if/elseif 语句即可。

关于javascript - 如何使用网络音频 API/javascript 操作 DOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20112871/

相关文章:

javascript - 防止点击底层div,react js

javascript - 层叠动画

javascript - Chrome 在新窗口而不是选项卡中打开链接列表?

javascript - 如何在 php 的表格中实现爆炸功能?

javascript - 使用ajax的聊天系统

javascript - 获取两个数组之间的精确匹配元素

javascript - 在 THREE.js 中使用纹理

jquery - 如何使用按钮更改谷歌地图的大小

jquery - 如何向该菜单项添加事件类?

html - 使用随机类名更改 div 的宽度