dwitter icon indicating copy to clipboard operation
dwitter copied to clipboard

Helper addition: M (mouse coordinate translation)

Open FireyFly opened this issue 8 years ago • 3 comments
trafficstars

I wanted to see if I could add an interactive element to a dweet, so I decided to attach a mousemove listener to take the mouse coordinate into account. Now, paying for the cost of adding an event listener and whatnot is fair game, but I didn't anticipate how expensive it'd be just to get something canvas-usable out of the mouse event. In the end I dweeted this little paint demo.

The annoying boilerplate-y part is the computation of the mouse (x,y) coordinate in relation to canvas coordinates, especially when taking different resolutions (non-fullscreen, fullscreen at different resolutions) into account. It seems reasonable to suggest a helper function to help deal with different resolutions, since that part seems to be meant to be transparent to the dweet (i.e., the canvas is always 1920×1080).

So, I suggest a helper function M:

M = (e) => [ e.offsetX/c.offsetWidth *1920,
             e.offsetY/c.offsetHeight*1080 ]

The dweeter could then get the mouse coordinates in canvas coordinates via a simple [X,Y]=M(e).

Thoughts? I do realise new helpers should have quite a lot of friction to being added, or we'll just end up abbreviating everything…

FireyFly avatar Feb 28 '17 15:02 FireyFly

Can we make it totally transparent for the dweet code? So we get the correct coordinates without having to add new helpers?

sigvef avatar Feb 28 '17 16:02 sigvef

Fwiw the first iteration was always in fullscreen, so if we have old demos relying on the coordinates being correct, transparently patching the coordinates would restore them!

sigvef avatar Feb 28 '17 16:02 sigvef

Oh hm… that would probably be better, yes. I'm not sure if there is a nice way to patch offsetX/offsetY up, I guess one could write a setter for c.onmousemove (and -up, -down, -click) and then call the real event hander with an object that inherits from the real MouseEvent object, but overrides those properties.

Something like this maybe? It's a bit icky though.

void function () {
  var handler
  Object.defineProperty(c, 'onmousemove', {
    get: function () {
      return handler
    },
    set: function (f) {
      if (handler != null) c.removeEventListener('mousemove', handler)
      handler = function (ev) {
        var ev_ = Object.create(ev)
        Object.defineProperty(ev_, 'offsetX', { get: () => ev.offsetX / c.offsetWidth  * c.width  })
        Object.defineProperty(ev_, 'offsetY', { get: () => ev.offsetY / c.offsetHeight * c.height })
        return f(ev_)
      }
      c.addEventListener('mousemove', handler, false)
    }
  })
}()

Edit: although this would mess up https://www.dwitter.net/d/809 (which only works in not-fullscreen currently)… not sure if messing with offsetX/offsetY would do more good or harm.

FireyFly avatar Feb 28 '17 17:02 FireyFly