【问题标题】:Smooth drag scrolling of an Isometric map - Html5等轴测图的平滑拖动滚动 - Html5
【发布时间】:2012-08-25 00:59:18
【问题描述】:

我已经实现了一个基本的等距图块引擎,可以通过用鼠标拖动地图来探索它。请看下面的小提琴并拖走:

http://jsfiddle.net/kHydg/14/

分解的代码是(CoffeeScript):

绘图功能

draw = ->
  requestAnimFrame draw
  canvas.width = canvas.width

  for row in [0..width]
    for col in [0..height]
      xpos = (row - col) * tileHeight + width
      xpos += (canvas.width / 2) - (tileWidth / 2) + scrollPosition.x
      ypos = (row + col) * (tileHeight / 2) + height + scrollPosition.y
      context.drawImage(defaultTile, Math.round(xpos), Math.round(ypos), tileWidth, tileHeight)

鼠标拖动滚动控制

scrollPosition =
  x: 0
  y: 0

dragHelper = 
  active: false
  x: 0
  y: 0


window.addEventListener 'mousedown', (e) =>
  handleMouseDown(e)
, false

window.addEventListener 'mousemove', (e) =>
  handleDrag(e)
, false

window.addEventListener 'mouseup', (e) =>
  handleMouseUp(e)
, false

handleDrag = (e) =>
  e.preventDefault()
  if dragHelper.active
    x = e.clientX
    y = e.clientY
    scrollPosition.x -= Math.round((dragHelper.x - x) / 28)
    scrollPosition.y -= Math.round((dragHelper.y - y) / 28)

handleMouseUp = (e) =>
  e.preventDefault()
  dragHelper.active = false

handleMouseDown = (e) =>
  e.preventDefault()
  x = e.clientX
  y = e.clientY
  dragHelper.active = true
  dragHelper.x = x
  dragHelper.y = y

问题

正如您从小提琴中看到的那样,拖动动作还可以,但并不完美。我将如何更改代码以使拖动动作更流畅?我想要的是您单击的地图点,以便在拖动时保持在鼠标点下方;和他们在这里做的一样:http://craftyjs.com/demos/isometric/

【问题讨论】:

    标签: html coffeescript isometric


    【解决方案1】:

    很多库都可以帮助解决此类问题。出于几个原因,我建议使用 d3 的数据操作能力来提供帮助。

    首先,在 d3 中,有一个拖动行为,其中存储了对象的原点,并在拖动开始时计算相对于原点的鼠标位置。然后,您可以使用鼠标的绝对位置来确定对象应该在哪里,并避免使用相对更改时出现的增量错误 - 当您开始四舍五入时会变得更糟,如上所述。

    dragMap = (d) ->  
      d.x = d3.event.x # d3.event.x, y are computed relative to the origin for you!
      d.y = d3.event.y 
    
    dragBehavior = d3.behavior.drag()
      .origin(Object) # equivalent to (d) -> d 
      .on("drag", dragMap)
    
    d3.select(canvas)
      .datum(x: 0, y: 0)  # Load your canvas with an arbitary origin
      .call(dragBehavior) # And now you can drag it!
    

    其次,通过使用 d3 的线性或其他数字刻度,您可以避免自己进行典型的绘图数学,这很容易出错,尤其是当您必须在所有地方都这样做时。在将拖动缩放 28 之前。在我当前的方法中,这是不必要的,但如果您将绘图算法更改为使用图块而不是像素,您可以更改此比例,它会自动将鼠标像素转换为图块大小。

    pixelToTile = d3.scale.linear()
      .domain([0, 1])
      .range([0, 1])  
    

    这是您在 d3 帮助下重新完成的小提琴。没有 dragHelper 和所有必要的无关代码。除了用于防止抗锯齿的画布绘制之外,所有 Math.round 调用也是不必要的。

    http://jsfiddle.net/kHydg/23/

    这不是更短更甜吗?

    附:等距实时浏览器游戏是一个很棒的主意。有时间我一定会尝试做一个。

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多