【问题标题】:How to add an onClick event handler to a canvas shape in Elm?如何将 onClick 事件处理程序添加到 Elm 中的画布形状?
【发布时间】:2015-10-28 04:19:05
【问题描述】:

是否可以在Graphics.Collage.square 中添加 onClick 事件处理程序?

我想知道点击的相对位置。

在 Javascript 中,我可以执行 this 之类的操作:

var canvas = document.getElementById('canvas');
var canvasPosition = {
  x: canvas.offsetLeft,
  y: canvas.offsetTop
};

canvas.addEventListener('click', function(event) {
  console.log(event.x - canvasPosition.x, event.y - canvasPosition.y);
}, false);

在 Elm 中可以做类似的事情吗?

示例将不胜感激。

【问题讨论】:

  • 我不确定,但我认为如果您需要这样的处理程序,您应该使用 elm-html 而不是(有些过时的)拼贴

标签: elm


【解决方案1】:

在 Elm 中,使用 Canvas 渲染,您应该使用 Mouse.clicks 信号并对信号的变化做出反应。这是一个可运行的示例,说明它是如何工作的:

import Graphics.Element exposing (Element, show)
import Mouse

clicks : Signal (Int, Int)
clicks =
  Signal.sampleOn Mouse.clicks Mouse.position

main : Signal Element
main =
  Signal.map show clicks

本质上,Mouse.clicks 是我们感兴趣的实际“事件”,所以无论何时发生,我们都会“采样”Mouse.position 信号以获取点击位置。

Signal.sampleOn 产生一个信号,当第一个参数信号(这里是鼠标点击)发生变化时,该信号会随着第二个参数信号(这里是鼠标位置)的值而更新。

现在,为了显示结果,我们还将位置映射到main 中的show 函数。

您也可以将此代码粘贴到http://elm-lang.org/try,编译并尝试单击右侧以查看它的工作原理。

【讨论】:

  • 我想知道用户点击了画布形状中的确切位置。知道形状在屏幕上的位置、尺寸和鼠标点击的位置 (Mouse.position),我可以计算出形状是否被点击,如果是,准确的位置。但是,如果形状不简单,计算起来就不是那么简单了。我想知道是否有更自动化的方法来实现这一点。
  • 是的,你可能知道形状在哪里。如果我没记错的话,Mouse.position 默认是相对于 Elm 画布的。唯一缺少的是碰撞检测,您可以使用例如package.elm-lang.org/packages/bakkemo/elm-collision/1.0.0
【解决方案2】:

我实现了proof-of-concept backbuffer test。这很 hacky,但它可能会完成这项工作。

如果您不喜欢这样,您唯一的选择是找到鼠标单击位置(这涉及从鼠标左上角原点的非常烦人的转换,y 向下到 Graphics.Collage 的居中原点,y 向上) ,然后进行几何碰撞检测。这对于圆形和轴对齐的矩形来说还不错,但我明白了,你想要一个通用的解决方案。

您也可以考虑使用 elm-svg,它具有典型的 DOM 事件,例如 mouseenter,尽管我不确定事件调度对于例如凸形状。或者你可以完全放弃 Elm(嗅探)并使用 D3.js 和 SVG。

【讨论】:

    猜你喜欢
    • 2019-05-17
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    相关资源
    最近更新 更多