【问题标题】:Getting the current coordinates after rotate/translate Canvas旋转/平移画布后获取当前坐标
【发布时间】:2021-08-12 04:37:05
【问题描述】:

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

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

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

这是sn-p

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()
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【问题讨论】:

    标签: javascript html5-canvas transformation


    【解决方案1】:

    您可以使用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();
    &lt;canvas id="canvas"&gt;&lt;/canvas&gt;

    【讨论】:

    • 这确实回答了我的问题。我还有几个,希望你能回答。与 getTransform 相比,这有什么缺点吗?它有什么优点吗?这种相同的技术可以用于所有形状吗?就像我决定做需要碰撞检测的旋转矩形一样。我真的很感激这个很好的答案。
    • getTransform 本身将返回一个 DOMMatrix,因此您可以从那里执行完全相同的操作,但是,如果您在变换位置重绘点而不更改其间的上下文变换,您的点将被变换两次.另请注意,如果需要,您可以将该 DOMMatrix 传递给setTransform。然后请注意,isPointInPath 考虑了当前上下文的转换,因此它也可能是一个选项。如果你需要一个单位矩阵,构造函数可能有更快的路径,但总而言之,没有大赢家,取决于你的项目结构。
    • 是的,您可以变换多边形的所有点来变换该多边形。
    • 你能告诉我我需要做什么来制作这些线条的动画并让它们旋转吗?我尝试什么似乎并不重要,它们不会设置动画,而只是继承初始位置。我尝试将它们放在动画循环中,并在外部使用递增的angle 变量。除了其他看起来它们应该起作用的东西。
    • 如果你只想画这些线,动画,那么最好的当然是直接使用上下文的变换:jsfiddle.net/t63adsu1如果你想更新你的点并且需要读回值,那么您必须每帧创建一个新的 DOMMatrix 和可能的新 DOMPoints,这可能非常低效。
    猜你喜欢
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 2022-11-30
    相关资源
    最近更新 更多