我已经在 Canvas 上画了一个圆圈和许多其他形状。我做了一个_rotate()函数,该函数旨在清除(删除内容) Canvas 并调用一个将绘制正方形的函数。问题在于单击“旋转”后,不仅绘制了正方形,而且绘制了圆形和矩形。我不知道代码可能有什么问题,所以我接受任何建议。
实际代码:

var c = document.getElementById("canv");
var canvas = c.getContext("2d");
//ciarka
function _rotate() {

canvas.clearRect(0, 0, 600, 400);
stvorec(Math.random());
return;
}


function stvorec(param) {
canvas.rotate(param*Math.PI/180);
canvas.fillStyle="green";
canvas.fillRect(350,50,50,50);
canvas.stroke();
}

function ciarka() {
canvas.beginPath();
canvas.moveTo(10,10);
canvas.lineTo(50,30);
canvas.lineTo(100,10);
canvas.lineTo(150,30);
canvas.lineTo(200,10);
canvas.lineTo(250,30);
canvas.lineTo(300,10);
canvas.lineTo(350,30);
canvas.lineTo(400,10);
canvas.lineTo(450,30);
canvas.lineTo(500,10);
canvas.lineTo(550,30);
canvas.lineTo(590,10);
canvas.stroke();
}


//obdlznik
function obdlznik() {
canvas.rect(150,150,100,50);
canvas.strokeStyle="black";
canvas.stroke();
}

//kruh
function kruh() {
canvas.beginPath();
canvas.arc(200,80,50,0,2.0*Math.PI);
canvas.stroke();
}
//stvorec

stvorec();
ciarka();
kruh();
obdlznik();

$("body").on("click", "#rot", function() {
   _rotate();
});

供引用的jsfiddle:jsfiddle

最佳答案

我在您的代码中看到了一些故障:

  • 对每个笔触/填充都执行beginPath()。
  • 在圆弧上执行closePath()以使其成为圆而不是360度圆弧。
  • 确保在执行.rotate
  • 之前使用.translate设置旋转点
  • stvorec(Math.random())仅产生0-1度的度角。

  • 不是小故障,只是命名上的奇怪:您将上下文变量称为canvas。上下文变量通常称为contextctx
    我不知道您的设计要求,但是这里有一些重构的工作代码:

    http://jsfiddle.net/m1erickson/5PuW9/
    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <style>
        body{ background-color: ivory; }
        canvas{border:1px solid red;}
    </style>
    <script>
    $(function(){
    
        var c = document.getElementById("canv");
        var canvas = c.getContext("2d");
    
        //ciarka
        function _rotate() {
            canvas.clearRect(0, 0, 600, 400);
            stvorec(Math.random()*360);
        }
    
        function stvorec(param) {
            canvas.save();
            canvas.beginPath();
            canvas.translate(350,50);
            canvas.rotate(param*Math.PI/180);
            canvas.fillStyle="green";
            canvas.fillRect(-25,-25,50,50);
            canvas.restore();
        }
    
        function ciarka() {
            canvas.beginPath();
            canvas.moveTo(10,10);
            canvas.lineTo(50,30);
            canvas.lineTo(100,10);
            canvas.lineTo(150,30);
            canvas.lineTo(200,10);
            canvas.lineTo(250,30);
            canvas.lineTo(300,10);
            canvas.lineTo(350,30);
            canvas.lineTo(400,10);
            canvas.lineTo(450,30);
            canvas.lineTo(500,10);
            canvas.lineTo(550,30);
            canvas.lineTo(590,10);
            canvas.stroke();
        }
    
        //obdlznik
        function obdlznik() {
            canvas.beginPath();
            canvas.rect(150,150,100,50);
            canvas.strokeStyle="black";
            canvas.stroke();
        }
    
        //kruh
        function kruh() {
            canvas.beginPath();
            canvas.arc(200,80,50,0,2.0*Math.PI);
            canvas.closePath();
            canvas.stroke();
        }
    
        //stvorec
        stvorec();
        ciarka();
        kruh();
        obdlznik();
    
        $("#test").click(function() {
           _rotate();
        });
    
    }); // end $(function(){});
    </script>
    </head>
    <body>
        <button id="test">Test</button><br>
        <canvas id="canv" width=600 height=400></canvas>
    </body>
    </html>
    

    [添加了beginPath和负坐标的说明]

    关于context.beginPath()

    将beginPath()和fill()/ stroke()视为上下文路径绘制命令周围的必需括号。

    如果您不对每组新的路径绘制命令都执行beginPath,则在调用下一个fill()/ stroke()时,将重新执行所有先前的路径绘制命令。

    例如:
    // circle#1
    
    context.beginPath();
    context.arc(100,100,10,0,Math.PI*2);
    context.closePath();
    context.fillStyle=”green”;
    context.fill();
    
    // circle#2  -- Note: no beginPath here
    
    context.arc(200,200,10,0,Math.PI*2);
    context.closePath();
    context.fillStyle=”green”;
    context.fill();
    

    在此示例中,将绘制圆#1。但是,由于在Circle#2的代码中没有beginPath,因此Circle#1将与circle#2一起被重绘为

    两个圆圈将变为绿色,因为每个beginPath仅允许您使用一种样式(将使用最后一个fillStyle =“green”,而将不使用红色样式)。

    关于旋转和负坐标

    要旋转,您应该告诉上下文要旋转的坐标点。

    这称为设置旋转点。默认情况下,上下文将旋转点设置在 Canvas 的左上角,因此每个后续图形都将绕 Canvas 的左上角旋转。

    要设置自己的旋转点,请执行context.translate(myCenterX,myCenterY)。

    然后所有后续抽奖将围绕myCenterX,myCenterY进行。

    可以认为这是在纸上握住铅笔尖。纸张绕着铅笔尖旋转。

    现在绘制矩形。

    由于上下文从矩形的左上角绘制矩形,因此矩形将围绕其自己的左上角旋转。

    要绕矩形的中心旋转,必须使用负坐标将矩形向左和向上拉,直到矩形位于旋转点的中心。

    这意味着您必须fillRect(-rectWidth / 2,-rectHeight / 2)使矩形在旋转点上居中。

    09-11 18:24