【问题标题】:How to rotate elements in canvas如何在画布中旋转元素
【发布时间】:2016-04-23 10:04:19
【问题描述】:

我有以下代码,它绘制出重复的小方块图案来填充画布大小(如背景)。我接下来要做的是慢慢旋转方块(在一个连续的循环中),但我似乎无法让它工作。它只是旋转整个画布。我读过我需要做一些上下文保存和恢复,但我不完全理解这是如何工作的。我已经注释掉了我不确定的部分,所以它正在工作。编辑:这是下面的codepen

var mainCanvas = document.getElementById("myCanvas");
var mainContext = mainCanvas.getContext('2d');

var canvasWidth = mainCanvas.width;
var canvasHeight = mainCanvas.height;

var requestAnimationFrame = window.requestAnimationFrame || 
                            window.mozRequestAnimationFrame || 
                            window.webkitRequestAnimationFrame || 
                            window.msRequestAnimationFrame;
var rotate = 1;

var elementWidth = 40;
var elementHeight = 40;
var canvasWidthGrid = canvasWidth / elementWidth;
var canvasHeightGrid = canvasHeight / elementHeight;

function drawShape() {
    mainContext.clearRect(0, 0, canvasWidth, canvasHeight);
    mainContext.fillStyle = "#EEEEEE";
    mainContext.fillRect(0, 0, canvasWidth, canvasHeight);

    mainContext.fillStyle = "#66d";
    mainContext.beginPath();
    //mainContext.save();

    for (var x = 0, i = 0; i < canvasWidthGrid; x+=90, i++) {
        for (var y = 0, j=0; j < canvasHeightGrid; y+=90, j++) {
            //mainContext.rotate( rotate );
            mainContext.fillRect (x, y, 45, 40);
            //mainContext.restore();
        }
    }

    requestAnimationFrame(drawShape);

    rotate++;
}

drawShape();

【问题讨论】:

    标签: javascript html animation canvas


    【解决方案1】:

    您的轮换代码存在几个问题:

    • context.rotate 中的旋转角度以弧度表示,而不是度数。
    • 始终围绕原点进行旋转。默认原点为 [0,0]。这就是为什么您的 rects 会按原样旋转的原因 - 所有 rects 都在画布的左上角旋转。

    因此,如果您希望矩形围绕其中心点旋转,您可以这样做:

    • 使用context.translate( rect.centerX, rect.centerY ) 将旋转点设置为矩形中心点
    • 以弧度表示的角度旋转。此代码将 30 度转换为弧度:context.rotate(30*Math.PI/180)
    • 绘制矩形有点棘手。 context.translate 导致新绘图起源于 [centerX,centerY] 因此您必须偏移绘图命令才能将绘图从中心矩形拉回左上角矩形:context.fillRect(-45/2,-40/2,45,50)
    • 完成转换(平移+旋转)后,您可以使用context.setTransform(1,0,0,1,0,0) 重置为默认方向

    以下是重构代码以使用这些新提示:

    var mainCanvas = document.getElementById("myCanvas");
    var mainContext = mainCanvas.getContext('2d');
    
    var canvasWidth = mainCanvas.width;
    var canvasHeight = mainCanvas.height;
    
    var rotate = 0;
    
    var elementWidth = 40;
    var elementHeight = 40;
    var canvasWidthGrid = canvasWidth / elementWidth;
    var canvasHeightGrid = canvasHeight / elementHeight;
    
    drawShape();
    
    
    function drawShape() {
        mainContext.clearRect(0, 0, canvasWidth, canvasHeight);
        mainContext.fillStyle = "#EEEEEE";
        mainContext.fillRect(0, 0, canvasWidth, canvasHeight);
    
        mainContext.fillStyle = "#66d";
        mainContext.beginPath();
    
        for (var x = 0; x<canvasWidth; x+=90) {
            for (var y = 0; y<canvasHeight; y+=90) {
                // set origin to center rect
                mainContext.translate(x+45/2,y+40/2);
                // rotate
                mainContext.rotate( rotate );
                mainContext.fillRect (-45/2, -40/2, 45, 40);
                // reset
                mainContext.setTransform(1,0,0,1,0,0);
            }
        }
    
        requestAnimationFrame(drawShape);
    
        rotate+=Math.PI/90;
    }
    body{ background-color: ivory; }
    canvas{border:1px solid red; margin:0 auto; }
    &lt;canvas id="myCanvas" width=360 height=360&gt;&lt;/canvas&gt;

    【讨论】:

    • 非常感谢。从那以后,我会以另一种方式工作,但会采用您提供的技巧并将其应用到我现在拥有的内容中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2014-09-23
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 2016-01-12
    相关资源
    最近更新 更多