You have a race condition because you set your offflag
to true and immediately readjust the slider, but the async task only gets to the flag after setting the slider again itself. This logic here should be a bit more robust, async code is always more complicated to reason about than sync code:
function plot_random_with_button()
f = Figure()
ax = Axis(f[1, 1])
buta = Button(f[2, :], label="Animate", tellwidth=false)
buts = Button(f[3, :], label="Stop", tellwidth=false)
sl = Slider(f[4, :], range=range(0, 2 * pi, 50))
x = Observable(range(0, 2 * pi, 100))
y = lift(x, sl.value) do x, p
cos.(x .+ p)
end
p = plot!(x, y)
taskref = Ref{Union{Nothing,Task}}(nothing)
should_close = Ref(false)
on(buta.clicks) do _
if taskref[] === nothing
taskref[] = @async begin
for val in Iterators.cycle(sl.range[])
sleep(1 / 30)
set_close_to!(sl, val)
should_close[] && break
end
should_close[] = false
end
end
Consume(true)
end
on(buts.clicks) do _
if taskref[] !== nothing && !should_close[]
should_close[] = true
wait(taskref[])
taskref[] = nothing
set_close_to!(sl, 0)
end
Consume(true)
end
f
end
plot_random_with_button()