Closed joelgrus closed 8 years ago
I hope this is the right venue to ask this kind of question.
Sure!
As you pointed out, the issue is that runFlareDrawing
expects a UI Drawing
, i.e. some interface that produces a pure value (a Drawing
). As you have to run an effectful computation to generate that Drawing
, you cannot use runFlareDrawing
.
You can solve this by using runFlareWith
instead (in your case, a = Int
):
runFlareWith :: forall e. ElementId
-> (a -> Eff (dom :: DOM, channel :: CHANNEL | e) Unit)
-> UI e a
-> Eff (dom :: DOM, channel :: CHANNEL | e) Unit
As the second argument, this expects a custom function that can run any effectful computation (for you, eff
includes RANDOM
and Canvas
). You can provide your own rendering function, something like:
drawRandomPoints :: forall eff. Context2D
-> Int
-> Eff (random :: RANDOM, canvas :: Canvas | eff) Unit
drawRandomPoints ctx n = do
clearRect ctx { x: 0.0, y: 0.0, w: width, h: height }
drawing <- randomPoints n
render ctx drawing
Finally, in your main function, you would call runFlareWith
instead:
main = do
Just canvas <- getCanvasElementById "canvas"
ctx <- getContext2D canvas
let ui = intRange "numPoints" 1 100 10
runFlareWith "controls" (drawRandomPoints ctx) ui
You can try it out here: http://sharkdp.github.io/try-flare/?gist=bdb4548abb6103be3e2a
@joelgrus Can this be closed?
Question and answer were very helpful.
An updated sample for this using latest purescript would be nice to have.
I've added it as example 17 in this gist: https://gist.github.com/oblitum/90cbf5338f55321a9d975f0588a711cd
I've finished a more complete sample which I incorporated in a blog post, it's still small:
You may feel free to incorporate it to the repository. Consider it public domain.
Notice that for now this one has moved the random computation outside of the controller, example 17 above is more correct in this aspect. Now... it seems I got back to this issue. How can I get the reset button to always reset the random points to a new initial random state instead of a static one... (since I'm managing model
's state through usage of foldp
, which is UI code, not controller)?
I've noticed also that that technique of using foldp
to start/reset the animation while having an internal animationFrame
seems to turn framerate quiter slower (running just the view
instead of the resetView
is faster). Sadly I dunno how to do the same (having start and reset state) in a different way (not running animationFrame
internally to a foldp
).
@sharkdp I'd like to know your judgement regarding this. I'm feeling I'm already hitting the limitations with Flare here (I'm not sure)? I'm just starting in FP again because of PureScript but the way I've done state management of buttons seems a bit contrived, restrictive and resource hungry (foldp
with animationFrame
). And I really wished to get back to the state of example 17, with a effectful computation (random) as the controller, while also, having the buttons and animation working like they are currently.
Sorry for the late answer.
I've finished a more complete sample which I incorporated in a blog post
Very nice!
You may feel free to incorporate it to the repository. Consider it public domain.
Thanks, I've added a link in the README.
How can I get the reset button to always reset the random points to a new initial random state instead of a static one...
has this been resolved in the mean time?
has this been resolved in the mean time?
No, I haven't touched the code since then, but I'd be interested in a flare sample of that, I'm still at https://github.com/sharkdp/purescript-flare/issues/14#issuecomment-228087969 state.
Right now I'm trying to finish "PureScript by Example", so in those samples I touched subjects which I was not familiar with. After the book I'd go about studing other libs and flare to check whether I've hit the limit with flare and it would be more natural using pux, or other lib.
Thanks, I've added a link in the README.
Thanks!
Sadly I dunno how to do the same (having start and reset state) in a different way (not running animationFrame internally to a foldp).
Currently, I cannot think of any other way, either. I was thinking about saving a "reset time" every time you press "reset", but that would also require you to pass the animationFrame
signal through foldp
.
You could probably nest two Flare UIs. The outer one would completely re-start the inner Flare, whenever "reset" is clicked. But ...
I'm feeling I'm already hitting the limitations with Flare here (I'm not sure)?
Quite possible. I encourage you to try out different PureScript UI frameworks. Flare is really only suited for "spreadsheet-like" UIs and the only way to incorporate "mutable state" is by using foldp
.
I'm closing this, as the initial issue is resolved, I think. But let me know if you find out something else.
Say I would like a slider to choose a number
n
and then plotn
random points.I can do this easily if the points are deterministic, but once they're random I need to generate them in an
Eff (random :: RANDOM | e)
context, and it's not obvious to me how to sequence that with the UI applicative. (I tried a number of things, but none of them worked.)See example (and non-example): https://gist.github.com/joelgrus/b27c12fc159367ea2440
I hope this is the right venue to ask this kind of question. Thanks!