Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best place for SVG FFI #8

Open
costructuralist opened this issue Aug 27, 2018 · 3 comments
Open

Best place for SVG FFI #8

costructuralist opened this issue Aug 27, 2018 · 3 comments

Comments

@costructuralist
Copy link
Contributor

costructuralist commented Aug 27, 2018

I have implemented an clientToSvgCoordinates FFI function to convert from screen coordinates to SVG coordinates using the getScreenCTM Javascript function (see http://svgdiscovery.com/E/Ed.htm and https://developer.mozilla.org/en-US/docs/Web/API/SVGGraphicsElement#Methods).

I think it would be nice to have this function available in purescript-halogen-svg itself - where do you think is the best place to add it (and related FFI functions)?

Here's the Javascript code:

"use strict";

exports.clientToSvgCoordinates = function (window) {
  return function (svgElementName) {
    return function (clientX) {
      return function (clientY) {
        var svgElement = window.document.getElementById(svgElementName);
        var position = svgElement.createSVGPoint();
        position.x = clientX;
        position.y = clientY;
        var matrix = svgElement.getScreenCTM();
        var svgCoordinates = position.matrixTransform(matrix.inverse());

        return { x: svgCoordinates.x, y: svgCoordinates.y };
      }
    }
  }
};
@kwohlfahrt
Copy link
Owner

Ah, that'd be useful. This would be used through the Effects module now right? I haven't used halogen much since that batch of changes... But if that's the case, I have no problem with dropping in a Svg.Effects module.

In terms of the implementation I'd take an element directly and leave it up to the user to fetch that element using e.g. getElementById. Does that seem sensible?

@costructuralist
Copy link
Contributor Author

It is being used very simplistically in my code currently:

foreign import clientToSvgCoordinates :: forall e. Web.HTML.Window.Window -> String -> Number -> Number -> Position

and then in eval:

eval (NodeMouseDown mouseEvent nodeId next) = do
      state <- H.get
      case button mouseEvent of
        0 -> do 
               window <- H.liftEffect $ DH.window
               let x = toNumber $ clientX mouseEvent
               let y = toNumber $ clientY mouseEvent
               let drawingCoordinates = clientToSvgCoordinates window state.svgElement.name x y
...

So I was thinking about just adding the foreign import to a module, like Svg.Effects as you suggested. It could probably be streamlined some more - but I'll leave those architectural decisions to you!

Looking at that name now, it would probably be more descriptive if it's screenToSvgCoordinates instead.

@epost
Copy link

epost commented May 16, 2019

@costructuralist At Statebox, we have some similar code, as well as FFI functions to start SVG animations and such things: statebox@fa7a0c1#diff-0b00078fa9da87176b5c60d0360a4591R3, so perhaps they should be considered here as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants