HTML5 canvas - rotate object without moving coordinates

前端 未结 2 1277
谎友^
谎友^ 2020-12-08 07:20

What I have is this: \"Tank\"

What I want is to rotate the red rectangle e.g. 20 degrees, but

相关标签:
2条回答
  • 2020-12-08 07:52

    Sounds like you want to rotate the rect around its centerpoint.

    Red rectangle is original, Yellow rectangle is rotated around the centerpoint.

    enter image description here

    To do that you need to first context.translate to the rect's centerpoint before rotating.

    // move the rotation point to the center of the rect
    
        ctx.translate( x+width/2, y+height/2 );
    
    // rotate the rect
    
        ctx.rotate(degrees*Math.PI/180);
    

    Note that the context is now in its rotated state.

    That means drawing position [0,0] is visually at [ x+width/2, y+height/2 ].

    So you must draw the rotated rect at [ -width/2, -height/2 ] (not at the original unrotated x/y).

    // draw the rect on the transformed context
    // Note: after transforming [0,0] is visually [-width/2, -height/2]
    //       so the rect needs to be offset accordingly when drawn
    
        ctx.rect( -width/2, -height/2, width,height);
    

    Here is code and a Fiddle: http://jsfiddle.net/m1erickson/z4p3n/

    <!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 canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
    
        var startX=50;
        var startY=80;
    
        // draw an unrotated reference rect
        ctx.beginPath();
        ctx.rect(startX,startY,100,20);
        ctx.fillStyle="blue";
        ctx.fill();
    
        // draw a rotated rect
        drawRotatedRect(startX,startY,100,20,45);
    
        function drawRotatedRect(x,y,width,height,degrees){
    
            // first save the untranslated/unrotated context
            ctx.save();
    
            ctx.beginPath();
            // move the rotation point to the center of the rect
            ctx.translate( x+width/2, y+height/2 );
            // rotate the rect
            ctx.rotate(degrees*Math.PI/180);
    
            // draw the rect on the transformed context
            // Note: after transforming [0,0] is visually [x,y]
            //       so the rect needs to be offset accordingly when drawn
            ctx.rect( -width/2, -height/2, width,height);
    
            ctx.fillStyle="gold";
            ctx.fill();
    
            // restore the context to its untranslated/unrotated state
            ctx.restore();
    
        }
    
    }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <canvas id="canvas" width=300 height=300></canvas>
    </body>
    </html>
    
    0 讨论(0)
  • 2020-12-08 08:01

    You can use a simple function to do this as an alternative to translate and rotate:

    This function will let you draw a line starting at x and y, and end at length at angle:

    function lineToAngle(ctx, x1, y1, length, angle) {
    
        angle *= Math.PI / 180;
    
        var x2 = x1 + length * Math.cos(angle),
            y2 = y1 + length * Math.sin(angle);
    
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
    
        return {x: x2, y: y2};
    }
    

    Usage:

    lineToAngle(ctx, x, y, length, angle);
    

    Demo

    var canvas = document.querySelector('canvas'),
        ctx = canvas.getContext('2d'),
        x = 100, y =50, length = 40, angle = 0, dlt = -2;
    
    (function animate() {
        
        //clear
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        ctx.beginPath();
        lineToAngle(ctx, x, y, length, angle);
        ctx.lineWidth = 10;
        ctx.stroke();
    
        angle += dlt;
        if (angle < -90 || angle > 0) dlt = -dlt;
        
        requestAnimationFrame(animate);
    })();
    
    function lineToAngle(ctx, x1, y1, length, angle) {
    
        angle *= Math.PI / 180;
        
        var x2 = x1 + length * Math.cos(angle),
            y2 = y1 + length * Math.sin(angle);
        
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
    
        return {x: x2, y: y2};
    }
    body {background-color:#555557}
    canvas {background:#ffffd;border:1px solid #000}
    <canvas></canvas>

    enter image description here

    0 讨论(0)
提交回复
热议问题