猿问

Canvas HTML5:在 mousemove 上显示直角坐标

我目前正在使用HTML5 Canvas开发一个图像编辑器,当鼠标悬停在画布上时,我在检测图像坐标时遇到了问题。

我在用矩形剪断的代码中复制了这个问题:

什么时候:

  • 红色部分是画布的边框。画布大小为400x400 像素

  • 绿色部分是模拟图像的矩形。矩形大小为200x200 像素

  • 在 mousemove 事件中,显示在画布的底部坐标。

  • 蓝色文字,是我想要的(现在坐标不是那些,是画布的)

我想要什么,但我不知道该怎么做:

  • 在 mousemove 上,我想显示矩形的坐标而不是画布坐标。即(0, 0)画布的将变为负值。(0, 0)底部显示的应该与蓝色文字相对应。

  • 更改 ZOOM 属性后它也应该工作。示例中的 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。但是,更改缩放后未显示正确的坐标。


holdtom
浏览 131回答 1
1回答

肥皂起泡泡

您必须将 ZOOM 值添加到 X 和 Y 计算中,如下例所示。我使用 Math.round 方法作为最终的 X 和 Y 值是一个长分数。const RECT_SIZE = 200const ZOOM = 1.4const 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)=>{&nbsp; const {top, left} = event.target.getBoundingClientRect();&nbsp; const zoomX = Math.round((event.clientX - left - (canvas.width / 2 - ((RECT_SIZE * ZOOM) / 2)))/ZOOM);&nbsp; const zoomY = Math.round((event.clientY - top - (canvas.height / 2 - ((RECT_SIZE * ZOOM) / 2)))/ZOOM);&nbsp; res.textContent = `X: ${zoomX} - Y: ${zoomY}`;});function transformedPoint(x, y) {&nbsp; svgPoint.x = x&nbsp; svgPoint.y = y&nbsp; return svgPoint.matrixTransform(xform.inverse())}// SCALING CANVASctx.translate(pt.x, pt.y)ctx.scale(ZOOM, ZOOM)ctx.translate(-pt.x, -pt.y)// SETTING SOME DEFAULTSctx.lineWidth = 1ctx.strokeStyle = 'green'ctx.fillStyle = 'blue'// DRAWING A REACTANGLEctx.beginPath()ctx.strokeRect(X, Y, RECT_SIZE,&nbsp; 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 {&nbsp; border: 1px solid red;}<canvas width="400" height="400"}></canvas><div class="res" />
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答