javascript 在HTML5 Canvas中围绕其轴旋转正方形?

ebdffaop  于 2023-09-29  发布在  Java
关注(0)|答案(5)|浏览(111)

我想创建一个函数,使正方形绕其轴旋转。

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.
}

如何做到这一点?

whhtz7ly

whhtz7ly1#

谢谢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

rbl8hiat

rbl8hiat2#

如果你不想处理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>

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

zzzyeukh

zzzyeukh3#

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

a11xaf1n

a11xaf1n4#

以下是我意见:

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();

ctx 2是旧位置,ctx是形状的新位置。你必须根据你想定位的形状,用相同的x,y坐标平移形状。然后你必须输入ctx.fillRect(x,y,w,h);的值,保持x和y作为-ve值(高度和宽度的一半,以保持它在画布的对角线上,否则改变来操纵它)。和h,w作为期望值。

DMEO

u0njafvf

u0njafvf5#

这里有另一个解决方案

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

function rd(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min)
}

for (let i = 0; i < 10; i++) {
    drawRect(rd(0, 400), rd(0, 400))
}

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 / degrees, y + height / degrees);
    // rotate the rect
    ctx.rotate(degrees * Math.PI / 180);

    // draw the rect on the transformed context
    ctx.rect(-width / 2, -height / 2, width, height);

    ctx.fillStyle = "gold";
    ctx.fill();

    // restore the context to its untranslated/unrotated state
    ctx.restore();
}

function drawRect(x, y) {
  const squareSize = 50;
  const degrees = 60;

  // draw an unrotated reference rect
  ctx.beginPath();
  ctx.rect(x - squareSize/2, y - squareSize/2 , squareSize, squareSize);
  ctx.fillStyle = "blue";
  ctx.fill();

  // draw a rotated rect
  drawRotatedRect(x, y, squareSize, squareSize, degrees);

  // draw center coord reference point
  drawDot(x, y, 5)
}

function drawDot(x, y, size) {
  ctx.beginPath();
  ctx.arc(x , y, size, 0, 2 * Math.PI);
  ctx.fillStyle = 'black'
  ctx.fill();
}
canvas {
    border:1px solid red;
}
<canvas id="canvas" width=400 height=400></canvas>

相关问题