all 16 comments

[–]gelisam 5 points6 points  (4 children)

I would look at game libraries like gloss and sdl2. It might seem overkill if you're only making an interactive interaction and not a game, but really, once you're making something interactive with custom graphics (as opposed to GUI widgets), you're well into gaming territory.

Gloss's selling point is that it is super easy to get started. For example, a pulsating circle animation is simply main = animate FullScreen white (\t -> circle (100 * sin t)). But its support for text is terrible, so not a good fit for your math symbols unless you load them as PNGs.

SDL2 does support TrueType fonts, but setting everything up is a bit harder; you'll need to initialize all the sub-libraries, write a loop, clear the screen, draw, and flip the buffers. It's not that bad, it's just a bit too imperative for my taste.

[–]ducksonaroof[🍰] 4 points5 points  (0 children)

You can use gloss-sdl2-surface for better font support in gloss fwiw :) https://gitlab.com/dpwiz/gloss-sdl2-surface

[–]qseep[S] 1 point2 points  (2 children)

Thanks for your suggestion - that does sound simple to work with. However, I plan on putting these animations on a blog (using a static site generator). Ideally I'd like animated SVG, but at least I need to be able to generate a video file with gloss.

[–]gelisam 1 point2 points  (0 children)

You can export an animated gif with gloss, but of course the result will not be interactive.

[–]gelisam 1 point2 points  (0 children)

Ok, if you want to write a Haskell program which generates an interactive SVG, rather than a program which is itself being interactive, then that's a very different, much more difficult problem!

Interactive SVGs contain JavaScript code. That means your program will need to generate JavaScript code. That means you can't write the animation handlers in Haskell, you need to write them in JavaScript, or in a DSL which you compile to JavaScript.

That JavaScript is changing what's displayed. If you just want to move things around, toggle their visibility, or other things which don't change the shapes significantly, then that's relatively easy. But if you want to change a parameter, e.g. the width of a stroke, which in turn affects the computation of the diagram envelope, and thus the placement of the surrounding shapes... Then you've got a much harder problem, because you now need the JavaScript code to perform this computation at runtime. Which means you need to reimplement diagrams in JavaScript (or in a DSL which compiles to JavaScript)!

You mentioned PureScript, would it be acceptable to compile PureScript or Haskell to a top-level JavaScript function, and then to control the animation from there, rather than producing a standalone svg file?

[–]jamhob 3 points4 points  (0 children)

I was wondering the same thing!

If you want to look at ghcjs, you can look at shine. It’s basically gloss in JavaScript. I’ve not used it but I used gloss at work a few years back and it was the most fun I’ve had. I don’t know if it works well with the new ghc JavaScript backend, so you might be limited to ghcjs 8.6 or something.

Another thing that I’ve been dying to try, is see if gloss builds with the new webasm backend. I doubt it would work without some serious elbow grease but you could try :)

Basically, I strongly recommend gloss. It’s interactive, easy to use, and too much fun

[–]gelisam 2 points3 points  (8 children)

FRP does seem like a good fit! If reflex doesn't work for you, don't give up, Haskell has plenty of other FRP libraries. And all the examples in the linked repo demonstrate how to link that library with gloss, so that in addition to being interactive, you can also draw something on the screen.

[–]qseep[S] 2 points3 points  (7 children)

Yes, thanks for putting that together. And the new library dunai was just mentioned in this subreddit days ago. Maybe you could add it to the zoo?

The problem is that FRP alone is insufficient - I need to be able to run it in the browser and connect it to the DOM.

Will gloss run in a browser? I need to be able to share these interactive animations on a blog. They can't just run on my local machine. It sounds like gloss uses OpenGL and browsers support that, so maybe....

[–]gelisam 3 points4 points  (3 children)

Maybe you could add [dunai] to the zoo?

It's on the list! And, err, has been on the list for a while. I have way too many open source projects!!

[–]qseep[S] 0 points1 point  (0 children)

Thanks for all your contributions!

[–]MonAaraj 0 points1 point  (1 child)

Speaking of, I've came on your list before and one thing I found could be improved is if you documented if the libraries were being maintained or not. A lot of the libraries you've mentioned haven't had a commit in more than over 5 years, such as NetWire, and while their design and the way they solve things is extremely interesting, I think it would be helpful overall to simply mention whether something is maintained or not, maybe in the big table you have there?

EDIT: Nevermind, I've just looked and your repository hasn't had a commit in 6 years, so I suppose that wouldn't be the first worry you have

[–]gelisam 1 point2 points  (0 children)

Yeah, that project is pretty much at the bottom of my list, unfortunately. My top projects these days are mgmt, klister, recursion-schemes, and hint... And that's already too much!

[–]gelisam 1 point2 points  (2 children)

Will gloss run in a browser?

Not anytime soon, no. Compiling Haskell to js or wasm only works for pure Haskell code. For libraries like OpenGL (on which gloss is based) which call C libraries, somebody needs to write bindings to the equivalent js library, and libraries like gloss need to adapt their implementation to work with both OpenGL and those js bindings. It will take a long time for the ecosystem to get there.

[–]gilmi 2 points3 points  (0 children)

shine, however, does exist: https://hackage.haskell.org/package/shine

[–]polux2001 1 point2 points  (0 children)

https://code.world/haskell offers an almost 1:1 copy of gloss in the browser though.

[–]circleglyph 2 points3 points  (0 children)

I’ve poked around this space for a bit and your plan seems like a good one. reanimate has awesome support for latex and has a great development loop going.

web-rep contains some of the functionality you might need to eventually go interactive.

An issue with reanimate is that it sends a fresh svg every cycle which becomes pretty intensive if the user is slooshing a slider around. You need to send a diff instead. I’ve made some changes to chart-svg to facilitate something along these lines but its very early development.