Skip to content

Example of gloo_render::request_animation_frame #319

Open
@tad-lispy

Description

@tad-lispy

Hi! Thank you for all your efforts around Gloo. It's very nice.

I'm heaving trouble figuring out how to use gloo_render::request_animation_frame and would really appreciate a simple, yet practical example. Probably I'm just missing something basic, as I am quite inexperienced with Rust. An example could go a long way. Below are a few things I tried so far.

The simplest approach, basically as I would do it in JS.

fn main() {
    request_animation_frame(step);
}

fn step(timestamp: f64) {
    console::log!("Frame", timestamp);
    request_animation_frame(step);
}

This compiles, but produces no output. My understanding is that as soon as the reference to an AnimationFrame goes out of scope, the request is cancelled and the step callback never called. So the solution has to somehow keep the reference alive. With this in mind I tried the following (in context of a Yew app):

pub struct App {
    animation: Option<AnimationFrame>,
    // ...
}

impl Component for App {
    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Message::FormSubmitted => {
                self.animation = Some(request_animation_frame(|timestamp| {
                    console::log!("First frame", timestamp);
                    ctx.link().send_message(Message::Frame(timestamp));
                }));
            },
            
            Message::Frame(previous) => {
                console::log!("Frame message", previous);
                self.animation = request_animation_frame(move |timestamp| {
                    console::log!("Next frame duration ", timestamp - previous);
                    ctx.link().send_message(Message::Frame(timestamp));
                })
                .into();
            }

        }
        // rest of the update...
    }
    // rest of the impl...
}

I'm getting the following:

error[E0521]: borrowed data escapes outside of associated function
   --> src/ui.rs:137:38
    |
121 |       fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
    |                            ---  - let's call the lifetime of this reference `'1`
    |                            |
    |                            `ctx` is a reference that is only valid in the associated function body
...
137 |                       self.animation = request_animation_frame(|timestamp| {
    |  ______________________________________^
138 | |                         console::log!("First frame", timestamp);
139 | |                         ctx.link().send_message(Message::Frame(timestamp));
140 | |                     }).into();
    | |                      ^
    | |                      |
    | |______________________`ctx` escapes the associated function body here
    |                        argument requires that `'1` must outlive `'static`

This example is Yew specific, so probably only good for demonstration. With a basic example, I hopefully be able to integrate it with my Yew code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions