使用ctx.getTransformation()转换后获取画布鼠标坐标

尼克麦

我正在使用以下函数在执行旋转后获取画布上的鼠标坐标。

function getWindowToCanvas(canvas, x, y) {
  const ctx = canvas.getContext("2d");
  var transform = ctx.getTransform();
  var rect = canvas.getBoundingClientRect();
  var screenX = (x - rect.left) * (canvas.width / rect.width);
  var screenY = (y - rect.top) * (canvas.height / rect.height);

  if (transform.isIdentity) {
    return {
      x: screenX,
      y: screenY
    };
  } else {
    console.log(transform.invertSelf());
    const invMat = transform.invertSelf();
    return {
      x: Math.round(screenX * invMat.a + screenY * invMat.c + invMat.e),
      y: Math.round(screenX * invMat.b + screenY * invMat.d + invMat.f)
    };
  }
}

在阅读html5-canvas-transformation-algorithmbest-to-to-transform-mouse-coordinates-to-html5-canvass-transformed-context后,我使用了逆变换矩阵

我让用户用鼠标绘制矩形,变换后需要获取鼠标的x,y坐标,但是一旦画布旋转(例如旋转90度),则矩形将不再跟随鼠标指针。

有人知道我在做什么错吗?

尼克麦

感谢@MarkusJarderot和jsFiddle从未旋转的画布获取鼠标坐标,因此我能够获得接近完美的解决方案我不太了解,但是效果更好。

function getWindowToCanvas(canvas, e) {

 //first calculate normal mouse coordinates
  e = e || window.event;
  var target = e.target || e.srcElement,
    style = target.currentStyle || window.getComputedStyle(target, null),
    borderLeftWidth = parseInt(style["borderLeftWidth"], 10),
    borderTopWidth = parseInt(style["borderTopWidth"], 10),
    rect = target.getBoundingClientRect(),
    offsetX = e.clientX - borderLeftWidth - rect.left,
    offsetY = e.clientY - borderTopWidth - rect.top;
  let x = (offsetX * target.width) / target.clientWidth;
  let y = (offsetY * target.height) / target.clientHeight;

  //then adjust coordinates for the context's transformations
  const ctx = canvas.getContext("2d");
  var transform = ctx.getTransform();
  const invMat = transform.invertSelf();
  return {
    x: x * invMat.a + y * invMat.c + invMat.e,
    y: x * invMat.b + y * invMat.d + invMat.f
  };
}

剩下的唯一问题是,当旋转45度时,使用ctx.rect()绘制一个矩形会绘制一个相对于画布而非窗口平行的矩形,因此即使最终位于右侧,该矩形也会倾斜。地点。我想相对于窗口而不是画布绘制矩形。但是,这可能只是ctx.rect()的工作方式,以后需要更新。目前,这可以帮助其他人。

更新 找出原始错误。由于我不明白为什么我的原始功能无法正常工作,因此使用上述解决方案开始对其进行故障排除。事实证明,上面的代码不起作用的原因是因为console.log(transform.invertSelf())我在调试时正在调用以查看转换。这使变换变形。因此,当我var invMat = transform.invertSelf()打完电话后,我又将其倒转了!我应该注意“ invertSelf”中的“自我”。

现在该功能有效

function getWindowToCanvas(canvas, x, y) {
  var rect = canvas.getBoundingClientRect();
  var screenX = (x - rect.left) * (canvas.width / rect.width);
  var screenY = (y - rect.top) * (canvas.height / rect.height);
  const ctx = canvas.getContext("2d");
  var transform = ctx.getTransform();
  if (transform.isIdentity) {
    return {
      x: screenX,
      y: screenY
    };
  } else {
    //   console.log(transform.invertSelf()); //don't invert twice!!
    const invMat = transform.invertSelf();

    return {
      x: Math.round(screenX * invMat.a + screenY * invMat.c + invMat.e),
      y: Math.round(screenX * invMat.b + screenY * invMat.d + invMat.f)
    };
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用 ref 对画布进行反应,忽略调用 ref.current 和 ctx?

如何仅使用鼠标坐标清除(或取消绘制)画布?

ILNumerics:使用ILLinePlot获取鼠标坐标

在画布中使用ctx.scale()方法时,重新调整大小和旋转在fabricjs中不起作用吗?

画布:存在* border *时获取鼠标坐标

在画布上单击时获取鼠标坐标

从鼠标坐标获取画布像素位置

Android:使用缩放和平移的画布获取正确的坐标

1秒后隐藏画布ctx.rect()-Javascript

在Koa Middlware中使用ctx

Python:如何使用matplotlib.canvas单击鼠标获取坐标

使用鼠标单击获取matplotlib绘图图形python的坐标

使用Javascript进行CSS 3D转换后,获取div的真实2D顶点坐标

JS画布中ctx的旋转线

在没有ctx.scale的情况下将画布缩放到鼠标光标

缩放和平移画布后鼠标坐标不匹配

画布-在窗口调整大小时转换鼠标坐标

如何在 AppSync Resolver 中仅使用 `ctx.identity.cognitoIdentityId` 来获取相关的 Cognito 用户池用户数据?

在画布上获取鼠标坐标的边框偏移

使用CTX通过查询更新Elasticsearch

ctx请求正文未使用nodejs定义

使用 Apple Pencil 时如何从 HTML 画布绘制或获取指针坐标?

如何通过Parser ctx获取行号?

ctx.stroke() 和 ctx.fill() 会自动关闭画布中的路径吗?

使用鼠标在python tkinter画布上绘制并获取指向列表的点?

单击时使用传单地图库获取图像叠加层的像素坐标(单击鼠标右键)

使用正交相机从鼠标位置获取Three.js世界坐标

调整窗口大小时如何使用鼠标单击获取图像坐标?

JavaFX 如何使用鼠标光标从图表上的绘制点获取 (x, y) 坐标?