首页 > 解决方案 > 旋转/平移画布后获取当前坐标

问题描述

我一直在试图弄清楚如何使用.getTransform来确定我的每条线的 Ax1/y1点和 B 点x2/y2在平移和旋转之后将是什么。我找到了其他答案,但它们似乎并没有完全针对我需要的东西,我也没有完全理解返回的矩阵。

从提供的代码段中,您可以看到我的行总是返回它们的原始值。我知道有一个公式我只是不知道它或我将如何实现它。

我需要的是每一行的起点和终点。计划是将它们旋转(动画旋转)到任何角度,并将这些坐标用于射线投射。我之前已经从中心点或一个方向到另一个方向完成了此操作,但没有使用旋转方法使用这么多线。

这是片段

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d")
canvas.width = 200;
canvas.height = 180;

class Rays {
  constructor(x1, y1, x2, y2) {
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
  }
  draw() {
    ctx.save();
    ctx.translate(canvas.width/2,canvas.height/2);
    ctx.rotate(45 * (Math.PI/180))
    ctx.beginPath();
    ctx.strokeStyle = 'black';
    ctx.moveTo(this.x1, this.y1)
    ctx.lineTo(this.x2, this.y2)
    ctx.stroke();
    ctx.closePath();
    ctx.restore();
  }
}

let rays = [];
function createRays() {
  //due to translate i have to push some lines in the negative and some positive  this causes an overlap of one line in the center.
  for (let i=0; i < 26; i++) {
    let x1 =  i < 13 ? -10 * i : i * 10 - canvas.width/2 - 20;
    let y1 =  -canvas.height;
    let x2 =  i < 13 ? -10 * i : i * 10 - canvas.width/2 - 20;
    let y2 =  canvas.height;
    rays.push(new Rays(x1, y1, x2, y2));  
  }
}
//enter angle here
createRays();

let count = 0; //just used to stop it from constantly console logging rays.x1

function drawRays() {
  for (let i=0;i<rays.length; i++) {
    rays[i].draw();
    count < 1 ? console.log(rays[i].x1) : false;
  }
  count++
}
drawRays();

console.log(ctx.getTransform())

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = "lightgrey";
    ctx.fillRect(0,0,canvas.width,canvas.height)
    drawRays();
    requestAnimationFrame(animate)
}
animate()
<canvas id="canvas"></canvas>

标签: javascripthtml5-canvastransformation

解决方案


您可以使用提供方法的DOMPoint.matrixTransform(DOMMatrix)接口。

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d")
canvas.width = 200;
canvas.height = 180;

const mat = new DOMMatrix();
mat.translateSelf(canvas.width/2,canvas.height/2);
mat.rotateSelf(45);

class Rays {
  constructor(x1, y1, x2, y2) {
    const pt1 = new DOMPoint(x1, y1).matrixTransform(mat);
    const pt2 = new DOMPoint(x2, y2).matrixTransform(mat);
        
    this.x1 = pt1.x;
    this.y1 = pt1.y;
    this.x2 = pt2.x;
    this.y2 = pt2.y;
  }
  draw() {
    ctx.beginPath();
    ctx.strokeStyle = 'black';
    ctx.moveTo(this.x1, this.y1)
    ctx.lineTo(this.x2, this.y2)
    ctx.stroke();
  }
}

let rays = [];
function createRays() {
  //due to translate i have to push some lines in the negative and some positive  this causes an overlap of one line in the center.
  for (let i=0; i < 26; i++) {
    let x1 =  i < 13 ? -10 * i : i * 10 - canvas.width/2 - 20;
    let y1 =  -canvas.height;
    let x2 =  i < 13 ? -10 * i : i * 10 - canvas.width/2 - 20;
    let y2 =  canvas.height;
    rays.push(new Rays(x1, y1, x2, y2));  
  }
}
//enter angle here
createRays();

let count = 0; //just used to stop it from constantly console logging rays.x1

function drawRays() {
  for (let i=0;i<rays.length; i++) {
    rays[i].draw();
  }
  count++
}
ctx.fillStyle = "lightgrey";
ctx.fillRect(0,0,canvas.width,canvas.height)
drawRays();
<canvas id="canvas"></canvas>


推荐阅读