Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 未设置canvas.height时,在画布上以声音条形式绘制音频不会覆盖上次绘制_Javascript_Reactjs_Html5 Canvas_Audiocontext - Fatal编程技术网

Javascript 未设置canvas.height时,在画布上以声音条形式绘制音频不会覆盖上次绘制

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

我有下面的内容,其中我得到一个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();
}
然后它正确地显示音频,最后蓝线消失。但我想要一个固定的高度和宽度为我的画布。最终的结果应该是从一个中心圆出来的线条/声音条


有人知道为什么在音频播放结束后,当我没有评论该行时,蓝色行不会消失吗?

是的,如果没有其他元素在同一画布上为每个帧绘制,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,但在我发布的图片中,你注意到这些条大部分是从右侧和底部出来的。你有什么建议可以让它在中间的圆圈里更均匀吗?@Blindman67
source
不是
window
的属性,它是用
const
定义的<代码>窗口。文档是不可变的,所以不从
窗口
调用它是可以的
innerWidth
innerHeight
是可变的,直接表示窗口的状态,因此,将其称为
window.innerHeight
是有意义的,而且它也不太容易出错,因为未来的代码编辑器可能会认为它只是一个作用域变量,并最终在执行
innerWidth-=100
时弄乱整个页面。请小心推广您自己的项目,因为它可能会被视为垃圾邮件。有关更多信息,请参阅
canvas.height = window.innerHeight;
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);