Clemapfel / Mousetrap.jl

Finally, a GUI Engine made for Julia

Home Page:https://clemens-cords.com/mousetrap

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Animation longer than 10^7 seconds gives very inaccurate timestep value

LilithHafner opened this issue · comments

I'm trying to play an animation indefinitely and the closest I could find was using Animation(render_area, seconds(1e10)). However, setting a time span longer than about 1e7 breaks the invariant value * timespan = time_elapsed.

Here's a working example of the code I wrote which ran into this (I made it work by lowering the animation length)

using Mousetrap

main() do app::Application
    window = Window(app)
    set_title!(window, "Bouncing Ball")

    render_area = RenderArea()

    shape = Ellipse(Vector2f(0, 0), 0.2, 0.2, 128)
    add_render_task!(render_area, RenderTask(shape))

    aspect_ratio = Ref(1.0)
    Mousetrap.connect_signal_resize!(render_area, shape) do ::RenderArea, width::Integer, height::Integer, ::Shape
        aspect_ratio[] = width / height
        nothing
    end

    animation = Animation(render_area, seconds(1e5))
    on_tick!(animation, render_area) do self::Animation, value::Float64, ra
        t = value * 1e5
        x = abs(t % 4 - 2) - 1
        t *= Base.MathConstants.φ
        y = 1 - (t % 22 - 2)^2

        w = min(.2, .2 / aspect_ratio[])
        h = min(.2, .2 * aspect_ratio[])
        as_ellipse!(shape,
            Vector2f((1-w)x, (1-h)y),
            w,
            h,
            128
        )
        queue_render(ra)
    end


    set_child!(window, render_area)

    present!(window)

    play!(animation)
end

When I set the animation time to 1e10, it moves really really fast.

I can reproduce this, I'm not sure what's happening with the setting-animation-duration-really high, but if you want an animation to continue indefinitely, you may want to use a tick callback instead, which continues infinitely:

using Mousetrap

main() do app::Application
    window = Window(app)
    set_title!(window, "Bouncing Ball")

    render_area = RenderArea()

    shape = Ellipse(Vector2f(0, 0), 0.2, 0.2, 128)
    add_render_task!(render_area, RenderTask(shape))

    aspect_ratio = Ref(1.0)
    Mousetrap.connect_signal_resize!(render_area, shape) do ::RenderArea, width::Integer, height::Integer, ::Shape
        aspect_ratio[] = width / height
        nothing
    end

    # use tick-callback
    elapsed = 0
    set_tick_callback!(render_area, render_area) do clock::FrameClock, ra
        elapsed += as_seconds(get_time_since_last_frame(clock))
        t = elapsed
        x = abs(t % 4 - 2) - 1
        t *= Base.MathConstants.φ
        y = 1 - (t % 22 - 2)^2

        w = min(.2, .2 / aspect_ratio[])
        h = min(.2, .2 * aspect_ratio[])
        as_ellipse!(shape,
            Vector2f((1-w)x, (1-h)y),
            w,
            h,
            128
        )
        queue_render(ra)
        return TICK_CALLBACK_RESULT_CONTINUE 
        # always returning continue, means the callback will never be removed
    end

    set_child!(window, render_area)
    present!(window)
end

tick_callback is exactly what I (and I'm guessing anyone else using animations longer than 100 days) am looking for! Thanks.