Javascript <;帆布>;修复问题

Javascript <;帆布>;修复问题,javascript,html,canvas,Javascript,Html,Canvas,我尝试使用canvas标签来允许用户绘制形状,但绘制一条新线会导致所有其他线消失。我应该提到,这一问题存在于所有5个最流行的浏览器中(包括IE7、8和IE9beta) 守则: <!DOCTYPE html> <html> <head> <!-- ... --> <!-- (a script used to support canvas in IE7,8) --><!--[if lte IE 8]> <script ty

我尝试使用canvas标签来允许用户绘制形状,但绘制一条新线会导致所有其他线消失。我应该提到,这一问题存在于所有5个最流行的浏览器中(包括IE7、8和IE9beta)

守则:

<!DOCTYPE html>
<html>
<head>
<!-- ... -->
<!-- (a script used to support canvas in IE7,8) --><!--[if lte IE 8]>
<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
<![endif]-->
<script type="text/javascript">//<![CDATA[
    var cnvs, cntxt;
    window.onload = function () {
        cnvs = document.getElementById("cnvs");
        cntxt = cnvs.getContext("2d");
        //...
    };

    var lastX, lastY;
    function beginLine(x, y) {
        cntxt.moveTo(x, y);
        cntxt.save();
        lastX = x;
        lastY = y;
        cnvs.setAttribute("onmousemove", "preview(event.clientX, event.clientY);");
        cnvs.setAttribute("onmouseup", "closeLine(event.clientX, event.clientY);");
    }

    function closeLine(x, y) {
        cntxt.lineTo(x, y);
        cntxt.stroke();
        cntxt.save();
        cnvs.removeAttribute("onmousemove");
        cnvs.removeAttribute("onmouseup");
    }

    function preview(x, y) {
        cntxt.beginPath();
        cntxt.clearRect(0, 0, cnvs.width, cnvs.height);
        cntxt.restore();
        cntxt.moveTo(lastX, lastY);
        cntxt.lineTo(x, y);
        cntxt.stroke();
    }
//]]></script>
</head>
<body>
    <!-- ... -->
    <canvas id="cnvs" style="position:absolute;top:0;left:0;border:1px black solid;" onmousedown="beginLine(event.clientX, event.clientY);"></canvas>
    <p style="margin-top:200px;">(click and drag the mouse to draw a line)</p>
</body>
</html>

//

(单击并拖动鼠标绘制一条线)

这可能是一个保存/还原错误,但我找不到它


我尝试了两个不同的论坛:


但是没有人知道问题出在哪里。

您误解了保存和恢复方法的含义。它们保存的是画布状态而不是内容。 也就是说,当您发出canvas.save()时,您正在保存fillStyle、strokeStyle、lineWidth和lineJoin

解决问题的最简单方法是在内存中保留另一个相同大小的画布,然后在释放鼠标按钮后,清除并使用drawImage方法。或者,您可以将线推送到数组中,并每次重新绘制它们(这可能比在现有画布上绘制另一个画布更快)


另外,还有一个关于clearRect的提示。事实证明,这种方法非常慢。在您的情况下,您使用它的频率不足以对性能产生重大影响,但为画布对象指定相同的宽度和高度要快得多。

您可能会特别提到
保存
保存变换(旋转、平移和缩放)。