简体   繁体   English

重绘画布会不断覆盖其内容-clearRect()无法正常工作吗?

[英]Redrawing canvas keeps overwriting its content - clearRect() not working?

I'm using sliders to tinker some numeric parameters and redraw the graph of a function. 我正在使用滑块修改一些数字参数并重绘函数图。 Currently, only the topmost slider works. 当前,只有最上面的滑块起作用。

The problem is: instead of replacing the previous plot, each redraw writes over , quickly cluttering everything and definitely not being what I want. 问题是:不是取代了以前的情节,每个重绘写过来 ,迅速塞满一切,绝对不是我想要的。

Worst yet, I can't figure out why this is happening, since I seem to be clearing things properly. 最糟糕的是,我无法弄清楚为什么会这样,因为我似乎正在正确地清理事情。

The behaviour is the same either on last-version Firefox and Chrome. 行为与上一版Firefox和Chrome相同。

What might I be doing wrong? 我可能做错了什么?

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="utf-8">

    <title>Gerador Envelope</title>

</head>

<body onload="redraw();">

    <canvas id="Canvas" width="1000" height="200"></canvas><br/>

    <label>subida</label><input type="range" min="0" max="255" value="0" oninput="baseFreq = this.value; redraw();"/><br/>
    <label>platô</label><input type="range" min="0" max="255" value="0" oninput="redraw();"/><br/>
    <label>descida</label><input type="range" min="0" max="255" value="0" oninput="redraw();"/><br/>
    <label>repouso</label><input type="range" min="0" max="255" value="0" oninput="redraw();"/><br/>
    <label>mod. amp.</label><input type="range" min="0" max="255" value="0" oninput="redraw();"/><br/>
    <label>freq. mod.</label><input type="range" min="0" max="255" value="0" oninput="redraw();"/><br/>


    <script type="text/javascript">

        var baseFreq = 1;

        var canvas = document.getElementById('Canvas');
        var cx = canvas.getContext('2d');

        function redraw () {

            var w = canvas.width;
            var h = canvas.height;

            cx.save();

            cx.clearRect(0, 0, w, h);

            cx.fillStyle = '#ddd';
            cx.fillRect(0, 0, w, h);


            cx.translate(0, h/2);

            cx.moveTo(0,0.5);
            cx.lineTo(w,0.5);
            cx.stroke();  

            var array = [];
            var b = w;
            while(b--)
                array[b] = (b+1) / baseFreq; 

            var seno = [];
            seno = array.map(function(x) {
                    return Math.sin(x) * 20;
                });

            cx.moveTo(0, seno[0]);
            for (var x = 1; x < w; x++) {
                cx.lineTo(x, seno[x]);
            }
            cx.stroke();

            array.length = 0;
            seno.length = 0;

            cx.restore();
        }
    </script>


</body>
</html>

You need to start your line drawing with a beginPath call before you do your drawing commands and then end with stroke . 在执行绘制命令之前,您需要先通过beginPath调用开始绘制beginPath ,然后以stroke结束。 Otherwise you are just adding drawing commands to the same path every time you redraw. 否则,您每次重新绘制时都只是将绘制命令添加到同一路径。

cx.translate(0, h/2);
cx.beginPath();
cx.moveTo(0,0.5);

and you should lose the first stroke as well. 你会输掉第一stroke为好。 You don't need to call it twice. 您不需要两次调用。

cx.moveTo(0,0.5);
cx.lineTo(w,0.5);
//cx.stroke();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM