在 JS canvas 中绘制正弦波不执行任何操作
Drawing sinewave in JS canvas does not do anything
我写了以下代码来从 AudioBuffer 中绘制声波,但我得到的是 canvas 水平直线:
const { audioContext, analyser } = this.getAudioContext();
const source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
const canvas = document.getElementById('canvas');
const canvasCtx = canvas.getContext("2d");
let sinewaveDataArray = new Uint8Array(analyser.fftSize);
const drawSinewave = function() {
analyser.getByteTimeDomainData(sinewaveDataArray);
requestAnimationFrame(drawSinewave);
canvasCtx.fillStyle = 'white';
canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = "black";
canvasCtx.beginPath();
const sliceWidth = canvas.width * 1.0 / analyser.fftSize;
let x = 0;
for(let i = 0; i < analyser.fftSize; i++) {
const v = sinewaveDataArray[i] / 128.0; // byte / 2 || 256 / 2
const y = v * canvas.height / 2;
if(i === 0) {
canvasCtx.moveTo(x, y);
} else {
canvasCtx.lineTo(x, y);
}
x += sliceWidth;
}
canvasCtx.lineTo(canvas.width, canvas.height / 2);
canvasCtx.stroke();
};
source.start();
drawSinewave();
getAudioContext = () => {
AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
const analyser = audioContext.createAnalyser();
return { audioContext, analyser };
};
我正在寻找的最终结果类似于此处的第一个图像剪辑:https://meyda.js.org/
知道我错过了什么吗?
我认为需要进行两个小改动才能使其正常工作。
source.start()
需要执行以响应用户事件。可以使用带有点击处理程序的简单按钮来实现这一点。这是处理某些浏览器中存在的自动播放策略所必需的。
aReferenceToAButton.addEventListener('click', async () => {
await audioContext.resume();
source.start();
});
最后但同样重要的是,您需要通过 AnalyserNode
.
管道传输信号
source
.connect(analyser)
.connect(audioContext.destination);
希望对您有所帮助。
我写了以下代码来从 AudioBuffer 中绘制声波,但我得到的是 canvas 水平直线:
const { audioContext, analyser } = this.getAudioContext();
const source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
const canvas = document.getElementById('canvas');
const canvasCtx = canvas.getContext("2d");
let sinewaveDataArray = new Uint8Array(analyser.fftSize);
const drawSinewave = function() {
analyser.getByteTimeDomainData(sinewaveDataArray);
requestAnimationFrame(drawSinewave);
canvasCtx.fillStyle = 'white';
canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = "black";
canvasCtx.beginPath();
const sliceWidth = canvas.width * 1.0 / analyser.fftSize;
let x = 0;
for(let i = 0; i < analyser.fftSize; i++) {
const v = sinewaveDataArray[i] / 128.0; // byte / 2 || 256 / 2
const y = v * canvas.height / 2;
if(i === 0) {
canvasCtx.moveTo(x, y);
} else {
canvasCtx.lineTo(x, y);
}
x += sliceWidth;
}
canvasCtx.lineTo(canvas.width, canvas.height / 2);
canvasCtx.stroke();
};
source.start();
drawSinewave();
getAudioContext = () => {
AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
const analyser = audioContext.createAnalyser();
return { audioContext, analyser };
};
我正在寻找的最终结果类似于此处的第一个图像剪辑:https://meyda.js.org/
知道我错过了什么吗?
我认为需要进行两个小改动才能使其正常工作。
source.start()
需要执行以响应用户事件。可以使用带有点击处理程序的简单按钮来实现这一点。这是处理某些浏览器中存在的自动播放策略所必需的。
aReferenceToAButton.addEventListener('click', async () => {
await audioContext.resume();
source.start();
});
最后但同样重要的是,您需要通过 AnalyserNode
.
source
.connect(analyser)
.connect(audioContext.destination);
希望对您有所帮助。