How to add an onClick event handler to a canvas shape in Elm?

馋奶兔 提交于 2019-12-23 12:04:43

问题


Is it possible to add an onClick event handler to Graphics.Collage.square?

I'd like to know the relative position of the click.

In Javascript, I could do something like 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);

Is that possible to do something similar in Elm?

Example would be appreciated.


回答1:


In Elm, using the Canvas rendering, you should use the Mouse.clicks signal and react to changes in the signal. Here's a runnable example of how that would work:

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

In essence, Mouse.clicks are the actual "events" we are interested in, so whenever one happens, we "sample" the Mouse.position signal to get the click position.

Signal.sampleOn produces a signal that updates with the value of the second parameter signal (here, the mouse position) whenever there is a change in the first parameter signal (here, the mouse clicks).

Now, just to get the result showing, we are also mapping the position to the show function in main.

You can also paste this code to http://elm-lang.org/try, compile and try clicking the right-hand side to see it working.




回答2:


I implemented a proof-of-concept backbuffer test. It's pretty hacky but it might do the job.

If you don't like that, your only option is to find the mouse click location (which involves a very annoying conversion from the Mouse's top-left origin, y is down to Graphics.Collage's centered origin, y is up), and then do geometric collision detection. Which isn't too bad with circles and axis-aligned rectangles, but I get it, you want a general solution.

You can also consider using elm-svg which has typical DOM events like mouseenter, although I'm not sure how reliable the event dispatch is for e.g. convex shapes. Or you could abandon Elm entirely (sniff) and use D3.js with SVG.



来源:https://stackoverflow.com/questions/33382837/how-to-add-an-onclick-event-handler-to-a-canvas-shape-in-elm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!