【问题标题】:Drag objects in canvas在画布中拖动对象
【发布时间】:2010-12-30 22:29:34
【问题描述】:

我正在寻找一种易于使用的方法,将拖动行为分配给画布中的多个对象(图像、形状等)。有没有人有一个好方法或知道任何用于拖动对象的库?谢谢

【问题讨论】:

  • 你要拖动什么样的形状,圆形,盒子,多边形?每个人的工作方式略有不同。
  • 我还没有开始尝试形状。现在我只是想弄清楚如何将我添加到画布中的图像拖动到画布中。

标签: html canvas draggable drag


【解决方案1】:

创建您自己的鼠标事件需要一些工作 - 理想情况下,您应该创建或使用某种迷你库。我正在考虑在不久的将来创造这样的东西。无论如何,我在 jsFiddle 上创建了一个拖放演示,展示了如何拖动图像 - you can view it here

您可以像这样创建可拖动的图像:

var myImage = new DragImage(sourcePath, x, y);

如果您对此有任何疑问,请告诉我。希望对您有所帮助。

编辑

拖动多个图像时出现错误。 Here is a new version.

您可能想要查看的另一件事是easeljs,它有点像 AS3...鼠标事件拖动等...

【讨论】:

  • 试用了你的demo,暂时还可以。谢谢
  • 当您添加更多图像时,我注意到一些奇怪的行为。我想需要有一种方法来确保它一次只能拖动一个图像。
  • 你可以用一个变量来解决这个问题......一个布尔值......让我看看,我会更新我的答案
  • 没问题 :) - 我只是进一步更新了它......它仍然可以使用一些 z 排序。 jsfiddle.net/Zevan/QZejF/5
  • 是的......我有一个使用 offsetX/Y 的坏习惯,即使它几乎不能在任何浏览器中工作......只需将其更改为 clientX 和 clientY,它应该可以解决问题:@987654325 @如果你需要把画布放在舞台左上角以外的地方——你需要做更多的代码,如果你需要我可以发布——让我知道。
【解决方案2】:

与 SVG 或 HTML 不同,HTML 画布使用 非保留(或 立即)图形 API。这意味着当您在画布上绘制某些东西(如图像)时,不会留下关于该东西的知识。唯一剩下的是画布上的像素,与之前的所有像素混合。您不能真正拖动像素子集;一方面,它们“下方”的像素消失了。你需要做的是:

  1. 跟踪mousedown 事件并查看它是否在“正确”位置进行拖动。 (您必须跟踪哪些图像/对象在哪里,并执行鼠标点击检测。)
  2. 当用户拖动鼠标时,从头开始重新绘制整个画布,每次根据当前鼠标位置和初始 mousedown 位置之间的偏移量在新位置绘制图像。

我可能会建议的一些替代方案:

  • SVG
  • 纯 HTML
  • 多个分层画布,并将一个透明画布拖到另一个上。

HTML 画布适用于很多事情。用户与看似不同(但并非如此)的“元素”进行交互不是其中之一。

更新:以下是一些显示在画布上拖动的示例:

但是,这些都没有为您创建单独的库来跟踪您的形状。

【讨论】:

  • 我明白了。感谢您的澄清。我的计划是最终将我的代码变成一个简单的游戏。我想继续使用画布,因为听起来画布将来会有更多的浏览器支持。目前我不介意按照您上面概述的步骤进行操作,但理想情况下,我想找到一个可以插入代码中的库,它可以帮助我处理鼠标与元素的交互。
  • @Rigil - 我同意 Phrogz。当我第一次听说画布时,我认为它就像一个闪光灯表面,我们可以在没有闪光灯的情况下使用。然而正如他所说,画布上没有“对象”的层次结构,只有一大堆像素。移动一件东西,您将需要清除画布并重新绘制所有内容。
【解决方案3】:

KineticJS 就是一个这样的 Javascript 库,您可以专门用于动画

这是链接html5canvastutorials

【讨论】:

    【解决方案4】:

    画布和jCanvas

    您肯定会想查看jCanvas。它是 Canvas 的超级干净的包装器,它在不增加代码复杂性的情况下打开了许多大门。它让这样的事情变得轻而易举。

    例如,这里有一个与您所追求的内容接近的小沙盒,内置了拖动和重绘功能:

    Drawing an Arrow Between Two Elements.

    我冒险尝试使用 DIV 和 jQuery 做所有事情,但它总是在交互性和质量上有所欠缺。

    希望能帮助其他人,比如我。

    日本

    【讨论】:

    • 两个元素之间的绘制箭头好像坏了?
    • @fatfrog 你是对的。似乎指向沙箱的链接不再正确填充代码。我希望我已将代码复制到答案本身中。好吧,您肯定想在这里查看 jCanvas 作为解决方案,如果有人重做此示例的代码,请更新此答案。
    • 你试过 Fabric.js 吗?您如何将其与 jCanvas 进行比较?
    • @fatfrog 不,我没有。这个答案是从 5 年前开始的,所以不确定当时是否还在。但我们仍在使用 jCanvas,它非常好用。
    【解决方案5】:

    当您创建新对象时,无论它们是窗口、卡片、形状还是可拖动的图像,您都可以将它们存储在“当前未选择的对象”数组中。当您单击它们或选择它们或开始拖动它们时,您可以将它们从“未选择的对象”数组中删除。这样,您可以通过检查是否未选中来控制在特定 mousedown 事件或 mousemove 事件中可以移动的内容。如果它被选中,它将不在“未选中”数组中,您可以在拖动形状时将鼠标指针移到其他形状上,而不会拖动它们。

    创建要拖动的对象数组也有助于层次结构。画布最后绘制属于最前面对象的像素。因此,如果对象在数组中,您只需在数组中的元素中切换它们的实例,例如从 objectArray[20] 到 objectArray[4],当您遍历数组并绘制存储在数组元素中的对象时,您可以更改其他可以在其他对象的顶部或后面看到对象。

    【讨论】:

      猜你喜欢
      • 2016-04-18
      • 2018-04-11
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      相关资源
      最近更新 更多