Simpler interface for `Kino.animate/3`
BrooklinJazz opened this issue · comments
Right now, the interface for Kino.animate/3 is:
Kino.animate(100, 0, fn i ->
md = Kino.Markdown.new("**Iteration: `#{i}`**")
{:cont, md, i + 1}
end)
Would there be an interest in providing an alternative interface using ranges (or any collection)? I.e.
Kino.animate(1..10, fn i -> Kino.Markdown.new("**Iteration: `#{i}`**") end)
Configuration could be done with options such as :interval
(with the default being 1000
) and :repeat
(with the default being true
). I.e.
Kino.animate(1..10, fn i -> Kino.Markdown.new("**Iteration: `#{i}`**") end, interval: 100, repeat: false)
I'm happy to implement this if there's an interest!
Kino.animate
is a wrapper around Kino.Frame, so you can do this today as:
frame = Kino.Frame.new
for i <- 1..10 do
Kino.Frame.render(frame, Kino.Markdown.new("**Iteration: `#{i}`**"))
end
Or:
frame = Kino.Frame.new
for i <- Stream.interval(100) |> Stream.zip(1..10) do
Kino.Frame.render(frame, Kino.Markdown.new("**Iteration: `#{i}`**"))
end
We were even discussing getting rid of Kino.animate altogether but there was no conclusion.
To add my two cents to the discussion - I think that Kino.animate/3
is useful to demonstrate that animations are possible. It's also a nice wrapper that could be made even better. IMO for devs new to the library, it's not obvious that we can use Kino.Frame
to handle animations.
I suppose that could be handled with demo documentation in Kino.Frame
like you mentioned.
However, I like the lightweight option with Kino.animate/3
Just my two cents! I wouldn't be severely affected if y'all decided it was best to remove Kino.animate/3
, and I'd be happy to help with the documentation if that's the direction things go.
Please feel free to close this issue :) Thank you for your response @josevalim!
Yes, let's leave it open because the discussion also relates to Kino.Control.stream
. We should unify those as much as we can and I assume the range case would also be useful for streams.
The main thing about Kino.animate
is that it takes care of the frame and updates, so I would extend the API to either of those:
Stream.interval(100)
|> Stream.take(10)
|> Stream.map(fn i -> Kino.Markdown.new("**Iteration: `#{i}`**") end)
|> Kino.animate()
or
Stream.interval(100)
|> Stream.take(10)
|> Kino.animate(fn i -> Kino.Markdown.new("**Iteration: `#{i}`**") end)
The feed could very well be Kino.Control.stream
! @josevalim wdyt?