Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose synchronous render option on runtime object #340

Closed
jozefchutka opened this issue Nov 29, 2023 · 4 comments
Closed

Expose synchronous render option on runtime object #340

jozefchutka opened this issue Nov 29, 2023 · 4 comments

Comments

@jozefchutka
Copy link

jozefchutka commented Nov 29, 2023

I am using v2.7.4 with canvas, and managed to follow https://help.rive.app/runtimes/overview/web-js/low-level-api-usage in order to create my own renderLoop. My use case is however different as I want to create snapshots at particular times of rive animation.

The problem with the current API is that in order to have canvas rendered, one has to "seek" (call all the necessary artboard, renderer and animator methods) followed by two requestAnimationFrame:

animator.animations.forEach(animation => {
	animation.advance(delta);
	animation.apply(1.0);
});

artboard.advance(delta);
renderer.clear();
renderer.save();
rive.alignRenderer();
artboard.draw(renderer);
renderer.restore();
renderer.flush();

animator.handleLooping();
animator.handleStateChanges();
animator.handleAdvancing(delta);

// at this <canvas> is empty
runtime.requestAnimationFrame(() => {
	// at this point <canvas> is still empty but runtime is to draw it soon 
	runtime.requestAnimationFrame(() => {
		// <canvas> is finally rendered
	})
})

The workaround I am using is customized rive.js where I just inserted my own render method:

...h.requestAnimationFrame=d.requestAnimationFrame.bind(d);h.cancelAnimationFrame=d...

replaced by

...h.requestAnimationFrame=d.requestAnimationFrame.bind(d);h.render=()=>d.fb();h.cancelAnimationFrame=d

with this change in place I can replace rAF-s and simply call

...advancing, clearing, saving, drawing...
animator.handleAdvancing(delta);

runtime.render()
// <canvas> is rendered

I would like to propose a new render() method exposed on runtime object, so one can request rendering synchronously without having to involve animation frame request.

@zplata
Copy link
Contributor

zplata commented Dec 4, 2023

Thanks for bringing this up! If I understand your problem right, it sounds much like the request here: #336 (comment)

Where we have a list of deferred render calls that get invoked only in our wrapped rAF loop. We've got some staged changes on our end to expose a call as something like resolveRenderer() or resolveRendererCalls() on the rive API so you can call this and the draw calls should be invoked at that time, rather than in the wrapped rAF. I think this might be what you'd also want with your solution, but feel free to correct me if I'm mistaken. With this it might look like:

artboard.advance(delta);
renderer.clear();
renderer.save();
rive.alignRenderer();
artboard.draw(renderer);
renderer.restore();
renderer.flush();

animator.handleLooping();
animator.handleStateChanges();
animator.handleAdvancing(delta);
// NEW
rive.resolveRenderer();

This change should land hopefully soon here! We had to shift briefly to some other priorities but we have some tested changes on our end in a branch to introduce this.

@jozefchutka
Copy link
Author

Sounds like resolveRenderer should do the job. Looking forward to have it released

@zplata
Copy link
Contributor

zplata commented Feb 7, 2024

Hi sorry for the delay here, you can check out this API in v2.10.0. You just call rive.resolveAnimationFrame() at the end of the loop like in the snippet above. We're working on updating docs so that should reflect in the API descriptions soon, but feel free to check it out today.

@jozefchutka
Copy link
Author

Hi, I have checked resolveAnimationFrame() in v2.10.3 and confirm it works. Thanks for adding it, feel free to close the issue.

@zplata zplata closed this as completed Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants