Javascript 未设置canvas.height时,在画布上以声音条形式绘制音频不会覆盖上次绘制
我有下面的内容,其中我得到一个audioBuffer音频剪辑,然后我画了一圈声音条来可视化它:Javascript 未设置canvas.height时,在画布上以声音条形式绘制音频不会覆盖上次绘制,javascript,reactjs,html5-canvas,audiocontext,Javascript,Reactjs,Html5 Canvas,Audiocontext,我有下面的内容,其中我得到一个audioBuffer音频剪辑,然后我画了一圈声音条来可视化它: const { audioContext, analyser } = this.getAudioContext(); const source = audioContext.createBufferSource(); source.buffer = this.props.audioBuffer; analyser.fftSize = 256; source.connect(analyser).conn
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();
}
然后它正确地显示音频,最后蓝线消失。但我想要一个固定的高度和宽度为我的画布。最终的结果应该是从一个中心圆出来的线条/声音条
有人知道为什么在音频播放结束后,当我没有评论该行时,蓝色行不会消失吗?是的,如果没有其他元素在同一画布上为每个帧绘制,clearRect工作得很好。但是,如果您只想删除画布上的一个元素,它将不起作用
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
另一个问题是,您可能需要某些类型的事务效果(例如音频条淡出)通过特定元素的帧。
如果继续为一个元素绘制效果,则可以在这些帧中清除所有其他元素
我提出的解决方案是将所有元素保持在一个数组中。
然后使用布尔标记绘制数组,该标记决定是否绘制特定元素。设置画布大小将重置2D上下文状态并清除画布。如果添加行
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height)代码>将清除画布,而无需重新发送2D上下文状态的开销。顺便说一句,window
是全局性的,它的使用在您使用它的每个实例中都是多余的。大多数全局文件都不使用它,例如document
,source
,它们都是全局文件,例如window.document
,以及window.source
,那么为什么要选择一些使用它呢。这是有道理的。谢谢clearRect也解决了这个问题。这可能是一个附带问题@Blindman67,但在我发布的图片中,你注意到这些条大部分是从右侧和底部出来的。你有什么建议可以让它在中间的圆圈里更均匀吗?@Blindman67source
不是window
的属性,它是用const
定义的<代码>窗口。文档是不可变的,所以不从窗口
调用它是可以的innerWidth
和innerHeight
是可变的,直接表示窗口的状态,因此,将其称为window.innerHeight
是有意义的,而且它也不太容易出错,因为未来的代码编辑器可能会认为它只是一个作用域变量,并最终在执行innerWidth-=100
时弄乱整个页面。请小心推广您自己的项目,因为它可能会被视为垃圾邮件。有关更多信息,请参阅
canvas.height = window.innerHeight;
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);