【问题标题】:Rotate square on its axis in HTML5 Canvas?在 HTML5 Canvas 的轴上旋转正方形?
【发布时间】:2022-02-09 07:32:22
【问题描述】:

我想创建一个在其轴上旋转正方形的函数。

var halfWidth = canvas.width/2;
var halfHeight = canvas.height/2;

var x = halfWidth-10;
var y = halfHeight-10;
var w = 20;
var h = 20;
var deg = 45;

rotate(x, y, w, h, deg);

ctx.fillRect(x, y, w, h);

功能:

function rotate(x, y, w, h, deg) {
    // ctx.translate() and ctx.rotate()
    // goes here.
}

如何做到这一点?

【问题讨论】:

标签: javascript html html5-canvas rect


【解决方案1】:

感谢dr.dredel 提供链接。

var cx = canvas.width/2;
var cy = canvas.height/2;

var x = -10;
var y = -10;
var w = 20;
var h = 20;
var deg = 45;

ctx.save();

ctx.translate(cx, cy);
ctx.rotate(deg * Math.PI/180);

ctx.fillRect(x, y, w, h);

ctx.restore();

解释:

  • ctx.save()保存坐标系的当前状态。

  • ctx.translate(cx, cy) 将原点更改为画布中心

  • ctx.rotate(deg * Math.PI/180)将正方形旋转45度(注意参数是弧度,不是度数)

  • ctx.fillRect( x, y, w, h ) 绘制正方形

  • ctx.restore() 恢复坐标系的最后状态。

JS Fiddle link.

Another JS Fiddle link, with a HTML5 slider.

【讨论】:

    【解决方案2】:

    如果我没记错的话,所涉及的平移类似于首先平移到矩形的中心点,然后旋转所需的数量,然后进行绘制。或者可能先旋转,然后翻译,我有点生疏=)

    【讨论】:

      【解决方案3】:

      这是我的看法:

      JAVASCRIPT

      var canvas = document.getElementById("myCanvas");
      var ctx2 = canvas.getContext("2d");
      ctx2.fillStyle='#333';
      
      ctx2.fillRect(50,50,100,100);
      var ctx = canvas.getContext("2d");
      
      
      ctx.fillStyle='red';
      
      var deg = Math.PI/180;
      
      ctx.save();
          ctx.translate(100, 100);
          ctx.rotate(45 * deg);
          ctx.fillRect(-50,-50,100,100);
      ctx.restore();
      

      ctx2 是旧位置,ctx 是形状的新位置。您必须根据要放置形状的位置来平移具有相同 x,y 坐标的形状。然后,您必须将值输入到ctx.fillRect(x,y,w,h);keep x 和 y 作为 -ve 值(高度和宽度的一半以使其保持在画布的对角线上,否则更改以操纵它)。和 h, w 作为您想要的值。

      DMEO

      【讨论】:

        【解决方案4】:

        如果您不想处理 ctx.save() 之类的问题,有一种简单的方法可以计算旋转正方形的每个新点的位置。

        下面会画一个绿色方块,再画一个旋转了22.5°的红色方块。

        const ctx = document.querySelector("canvas").getContext("2d");
        
        ctx.fillStyle = "green";
        ctx.fillRect(50, 50, 50, 50)
        
        /**
         * 
         * @returns {[number, number]} (x3, y3)
         */
        function f(x1, y1, x2, y2, degrees) {
            const rad = degrees * Math.PI / 180;
            return [
                (x2 - x1) * Math.cos(rad) + x1 - (y2 - y1) * Math.sin(rad),
                (x2 - x1) * Math.sin(rad) + y1 + (y2 - y1) * Math.cos(rad)
            ]
        }
        
        ctx.fillStyle = "red";
        const centre = 75;
        /*
         * The centre of the square is at (75, 75)
         * The corner points are at:
         * (50, 50)
         * (100, 50)
         * (100, 100)
         * (50, 100)
         */
        
        ctx.beginPath();
        let [newX, newY] = f(centre, centre, 50, 50, 22.5);
        ctx.moveTo(newX, newY);
        
        [newX, newY] = f(centre, centre, 100, 50, 22.5);
        ctx.lineTo(newX, newY);
        
        [newX, newY] = f(centre, centre, 100, 100, 22.5);
        ctx.lineTo(newX, newY);
        
        [newX, newY] = f(centre, centre, 50, 100, 22.5);
        ctx.lineTo(newX, newY);
        
        [newX, newY] = f(centre, centre, 50, 50, 22.5);
        ctx.lineTo(newX, newY);
        
        ctx.fill();
        <canvas width=200 height=200 style="background:gray"></canvas>

        我把这张图放在一起认为它可能有助于可视化正在发生的事情。

        【讨论】:

          猜你喜欢
          • 2017-09-29
          • 1970-01-01
          • 2019-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-14
          • 2019-04-06
          • 2012-03-01
          相关资源
          最近更新 更多