简体   繁体   English

在 HTML Z6EA5359E01A41842884943125 上放大/缩小等距 map 后,获得正确的鼠标 position

[英]Get correct mouse position after zooming in/out an isometric map on HTML Canvas

Hi I am trying to create isometric graphic app with React, mostly base on the code here .您好我正在尝试使用 React 创建等距图形应用程序,主要基于此处的代码。

I achieved most of the functions (ie. zoom and scroll).我实现了大部分功能(即缩放和滚动)。 But hovering tiles after zooming gives me wrong mouse position (hover position).但是缩放后悬停的瓷砖给了我错误的鼠标 position(悬停位置)。

You can see what I mean here .你可以在这里看到我的意思。 You can zoom with scrolling vertically.您可以通过垂直滚动进行缩放。

When it is not zoomed in or out, hovering tile works correctly (tile color changes where the mouse positions).当它没有放大或缩小时,悬停磁贴可以正常工作(磁贴颜色会在鼠标位置发生变化)。 But after zooming out/in it is not working right.但是在缩小/缩小后它不能正常工作。

Does anyone know how to get the mouse position or tile index correctly after zooming in/out?有谁知道放大/缩小后如何正确获取鼠标 position 或平铺索引?

Implemented code can be found on my Github repo here实现的代码可以在我的 Github repo 上找到

Code snippet for getting target tile is below:获取目标图块的代码片段如下:

const handleHover = (x: number, y: number) => {
  const { e: xPos, f: yPos } = ctx.getTransform()
  const mouse_x = mouseRef.current.x - x - xPos
  const mouse_y = mouseRef.current.y - y - yPos

  const hoverTileX =
    Math.floor(
      mouse_y / Tile.TILE_HEIGHT + mouse_x / Tile.TILE_WIDTH
    ) - 1
  const hoverTileY = Math.floor(
     -mouse_x / Tile.TILE_WIDTH + mouse_y / Tile.TILE_HEIGHT
  )

  if (
    hoverTileX >= 0 &&
    hoverTileY >= 0 &&
    hoverTileX < gridSize &&
    hoverTileY < gridSize
  ) {
     const renderX =
        x + (hoverTileX - hoverTileY) * Tile.TILE_HALF_WIDTH
     const renderY =
        y + (hoverTileX + hoverTileY) * Tile.TILE_HALF_HEIGHT

     renderTileHover(ctx)(renderX, renderY + Tile.TILE_HEIGHT)
  }
}

I am not good at maths so I really need help...我数学不好,所以我真的需要帮助......

Thank you.谢谢你。

I figured out how to achieve this.我想出了如何实现这一点。 I will leave it here so anyone who has the same issue wont waste a lot of time for this kind of issue.我会把它留在这里,这样任何有同样问题的人都不会在这类问题上浪费很多时间。 My code is like this:我的代码是这样的:

/**
 * @param context canvas context 2d
 * @param inputX mouse/touch input position x (ie. clientX)
 * @param inputY mouse/touch input position y (ie. clientY)
 * @returns {x, y} x and y position of inputX/Y which map scale and position are taken into account
 */
export const getTransformedPoint = (context: CanvasRenderingContext2D, inputX: number, inputY: number) => {
    const transform = context.getTransform()
    const invertedScaleX = DEFAULT_MAP_SCALE / transform.a
    const invertedScaleY = DEFAULT_MAP_SCALE / transform.d

    const transformedX = invertedScaleX * inputX - invertedScaleX * transform.e
    const transformedY = invertedScaleY * inputY - invertedScaleY * transform.f

    return { x: transformedX, y: transformedY }
}

/**
 *
 * @param startPosition position where map start rendered (Position2D has {x: number, y: number} type)
 * @param inputX mouse/touch input position x (ie. clientX)
 * @param inputY mouse/touch input position x (ie. clientY)
 * @returns positionX, positionY: tile position x, y axis
 */
export const getTilePosition = (
    startPosition: Position2D,
    inputX: number,
    inputY: number
): { positionX: number; positionY: number } => {
    const positionX =
        Math.floor((inputY - startPosition.y) / TILE_HEIGHT + (inputX - startPosition.x) / TILE_WIDTH) - 1
    const positionY = Math.floor(
        (inputY - startPosition.y) / TILE_HEIGHT - (inputX - startPosition.x) / TILE_WIDTH
    )

    return { positionX, positionY }
}

// usage
const onClick = (e: MouseEvent) => {

        const { x: mouseX, y: mouseY } = getTransformedPoint(ctx, e.clientX, e.clientY)

        const { positionX, positionY } = getTilePosition(startPositionRef.current, mouseX, mouseY)
        
        // Do something with positionX and positionY...
        // ie.
        if (return positionX >= 0 && positionY >= 0 && positionX < GRID_SIZE && positionY < GRID_SIZE) {
            // code when a user clicks a tile within the map
        }
    }

I referenced this for calculating the mouse position when the map is zoomed out/in.当 map 被缩小/缩小时,我参考了这个来计算鼠标 position。

Try below试试下面

const handleHover = (x: number, y: number) => {
  // use the current scale of the canvas context
  const { a: scale, e: xPos, f: yPos } = ctx.getTransform()
  const mouse_x = (mouseRef.current.x - x - xPos) * scale
  const mouse_y = (mouseRef.current.y - y - yPos) * scale

  // rest of the code...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM