javascript - 未设置 canvas.height 时,在画布上将音频绘制为条形音箱不会覆盖上一次绘制
问题描述
我有以下内容,其中我得到了一个 audioBuffer 音频剪辑,然后我画了一圈条形音箱来可视化它:
const { audioContext, analyser } = this.getAudioContext();
const source = audioContext.createBufferSource();
source.buffer = this.props.audioBuffer;
analyser.fftSize = 256;
source.connect(analyser).connect(audioContext.destination);
source.start();
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext("2d");
// find the center of the window
let center_x = canvas.width / 2;
let center_y = canvas.height / 2;
let radius = 150;
const frequency_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(frequency_array);
const bars = analyser.frequencyBinCount;
const bar_width = 2;
animationLooper();
function animationLooper(){
//canvas.height = window.innerHeight;
// find the center of the window
center_x = canvas.width / 2;
center_y = canvas.height / 2;
radius = 50;
analyser.getByteFrequencyData(frequency_array);
for(let i = 0; i < bars; i++){
//divide a circle into equal parts
let rads = Math.PI * 2 / bars;
const bar_height = frequency_array[i] / 2;
// set coordinates
let x = center_x + Math.cos(rads * i) * (radius);
let y = center_y + Math.sin(rads * i) * (radius);
const x_end = center_x + Math.cos(rads * i)*(radius + bar_height);
const y_end = center_y + Math.sin(rads * i)*(radius + bar_height);
//draw a bar
drawBar(x, y, x_end, y_end, bar_width);
}
window.requestAnimationFrame(animationLooper);
}
function drawBar(x1, y1, x2, y2, width){
ctx.strokeStyle = "#1890ff";
ctx.lineWidth = width;
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.stroke();
}
HTML:
<canvas id="canvas" width="400" height="400" />
这会在音频播放完毕和绘图完成后产生。它应该恢复到没有蓝线。
但是,如果我在该行中发表评论
canvas.height = window.innerHeight;
然后它正确地可视化音频,最后蓝线消失。但我想要画布的固定高度和宽度。最终结果应该是从中心圆出来的线条/条形音箱。
有谁知道为什么当我没有评论那条线时,当音频播放完毕时蓝线不会消失?
解决方案
是的,如果您没有其他元素可以在每个帧的同一画布上绘制,则 clearRect 效果很好。但是,如果您只想删除画布上的一个元素,它将不起作用。
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
另一个问题是您可能需要某些类型的事务效果(例如音频条淡出)通过某个元素的帧。如果您继续为一个元素绘制效果,它可以清除这些帧期间的所有其他元素。
我想出的解决方案是将所有元素保存在一个数组中。然后使用布尔标记绘制数组,该标记决定是否为某个元素绘制。
推荐阅读
- python - 从 json 响应中删除前 6 行
- pyspark - 如何腌制 Spacy 模型以在 PySpark 函数中使用
- arrays - 为什么我不能将一个数组分配给 C 中的另一个数组
- java - 将 ArrayList 转换为 TreeMap
- java - RxJava PublishSubject 订阅不提供任何东西。订阅有什么问题吗?
- powershell - 从多个域的广告中搜索数据
- javascript - javascript MSE可以从中间播放分段的mp4吗?
- yarnpkg - 纱线安装错误“error:0909006C:PEMroutines:get_name:no start line”
- caching - 管理多个数据源
- mysql - 根据行中的标记获取变量 MIN Date