javascript - Canvas HTML5 : Display rect coordinates on mousemove

标签 javascript html canvas

我目前正在使用 开发图像编辑器HTML5 Canvas ,当鼠标悬停在 Canvas 上时,我在检测图像坐标时遇到问题。
我在一个用矩形剪断的代码中复制了这个问题:
Example
什么时候:

  • 红色部分是 Canvas 的边框。 Canvas 尺寸为 400x400 像素 .
  • 绿色部分是模拟图像的矩形。矩形大小为 200x200 像素 .
  • 在 mousemove 事件中,显示在 Canvas 的底部坐标处。
  • 蓝色文本,是我想要的(现在坐标不是那些,是 Canvas 的)

  • 我想要什么但我不知道该怎么做:
  • 在 mousemove 上,我想显示 矩形坐标 而不是 Canvas 坐标。即(0, 0) Canvas 的将变为负数。而显示的(0, 0)底部应与蓝色文本相对应。
  • 更改 ZOOM 后也应该可以工作属性(property)。示例中的 ZOOM 为 1 , 但在更改为 0.5 之后或 1.5应该以同样的方式工作。

  • 代码
    在下面,我分享了截取的代码,看看是否有人可以帮助我,因为我有点沮丧,而且我确信这很愚蠢。非常感谢!

    const RECT_SIZE = 200
    const ZOOM = 1
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
    const svgPoint = svg.createSVGPoint()
    const xform = svg.createSVGMatrix()
    const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')
    const res = document.querySelector('.res')
    const pt = transformedPoint(canvas.width / 2, canvas.height / 2)
    const X = canvas.width / 2 - RECT_SIZE / 2
    const Y = canvas.height / 2 - RECT_SIZE / 2
    
    function transformedPoint(x, y) {
      svgPoint.x = x
      svgPoint.y = y
      return svgPoint.matrixTransform(xform.inverse())
    }
    
    function mousemove(e) {
      const { left, top } = canvas.getBoundingClientRect()
      res.textContent = `X: ${e.clientX - left} - Y: ${e.clientY - top}`
    }
    
    // SCALING CANVAS
    ctx.translate(pt.x, pt.y)
    ctx.scale(ZOOM, ZOOM)
    ctx.translate(-pt.x, -pt.y)
    
    // SETTING SOME DEFAULTS
    ctx.lineWidth = 1
    ctx.strokeStyle = 'green'
    ctx.fillStyle = 'blue'
    
    // DRAWING A REACTANGLE
    ctx.beginPath()
    ctx.strokeRect(X, Y, RECT_SIZE,  RECT_SIZE)
    
    ctx.font = "12px Arial";
    ctx.fillText("0,0", X - 5, Y-10);
    ctx.fillText("200,200", X + RECT_SIZE - 15, Y + RECT_SIZE + 15);
    
    ctx.closePath()
    canvas {
      border: 1px solid red;
    }
    <canvas width="400" height="400" onmousemove="mousemove(event)"}></canvas>
    <div class="res" />

    换行:
    res.textContent = `X: ${e.clientX - left} - Y: ${e.clientY - top}`
    

    res.textContent = `X: ${e.clientX - left - X} - Y: ${e.clientY - top - Y}`
    
    ZOOM = 1 时显示正确的坐标.但是,更改缩放后不显示正确的坐标。

    最佳答案

    您必须将 ZOOM 值添加到 X 和 Y 计算中,如下例所示。我使用 Math.round 方法,因为最终的 X 和 Y 值是一个长分数。

    const RECT_SIZE = 200
    const ZOOM = 1.4
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
    const svgPoint = svg.createSVGPoint()
    const xform = svg.createSVGMatrix()
    const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')
    const res = document.querySelector('.res')
    const pt = transformedPoint(canvas.width / 2, canvas.height / 2)
    const X = canvas.width / 2 - RECT_SIZE / 2;
    const Y = canvas.height / 2 - RECT_SIZE / 2;
    
    canvas.addEventListener('mousemove',(event)=>{
      const {top, left} = event.target.getBoundingClientRect();
      const zoomX = Math.round((event.clientX - left - (canvas.width / 2 - ((RECT_SIZE * ZOOM) / 2)))/ZOOM);
      const zoomY = Math.round((event.clientY - top - (canvas.height / 2 - ((RECT_SIZE * ZOOM) / 2)))/ZOOM);
      res.textContent = `X: ${zoomX} - Y: ${zoomY}`;
    
    });
    
    function transformedPoint(x, y) {
      svgPoint.x = x
      svgPoint.y = y
      return svgPoint.matrixTransform(xform.inverse())
    }
    
    
    // SCALING CANVAS
    ctx.translate(pt.x, pt.y)
    ctx.scale(ZOOM, ZOOM)
    ctx.translate(-pt.x, -pt.y)
    
    // SETTING SOME DEFAULTS
    ctx.lineWidth = 1
    ctx.strokeStyle = 'green'
    ctx.fillStyle = 'blue'
    
    // DRAWING A REACTANGLE
    ctx.beginPath()
    ctx.strokeRect(X, Y, RECT_SIZE,  RECT_SIZE)
    
    ctx.font = "12px Arial";
    ctx.fillText("0,0", X - 5, Y-10);
    ctx.fillText("200,200", X + RECT_SIZE - 15, Y + RECT_SIZE + 15);
    
    ctx.closePath()
    canvas {
      border: 1px solid red;
    }
    <canvas width="400" height="400"}></canvas>
    <div class="res" />

    关于javascript - Canvas HTML5 : Display rect coordinates on mousemove,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63846100/

    相关文章:

    javascript - 单击时仅更改一个 <li> 元素的样式

    javascript - 如何创建一个每 1-8 秒递增 1 的计数器(随机)

    java - 使用 jsoup 提取 `th` header 显示特定值的表

    javascript - HTML5 Canvas : Mouse and polygon collision detection

    javascript - HTML5 Canvas - 绘制一条越来越粗到最后的线的最简单方法是什么?

    php - 在 PHP 中创建内联 'Jargon' 帮助程序

    javascript - 使用提交按钮将 html 数据检索到表单输入中

    jquery - 滚动具有绝对位置的内容

    javascript - 如何在具有相同样式但不同 ID 的输入元素上将按钮用作微调器

    javascript - 随机生成 HTML Canva 对象