`onDraw` doesn't trigger
smblee opened this issue · 14 comments
I noticed one of the EventType is Draw
but can't seem to get any callbacks.
rive.on(EventType.Draw, (ctx) => {
console.log(ctx);
});
^ this is the code i am running. I can't really find much documentation around this either.
Does this properly not exist?
Hi @smblee - I don't believe this is an exposed event you can subscribe to. Mind sharing where you found this property so we can fix up documentation?
Found it in the typescript definition. I believe it's an existing Enum under EventType
Then are there any similar event i can subscribe to without opting to the advanced
libraries? I just need to add some frame color detection every screen without interfering with the actual render itself
Ahh I see what you mean - our Android and iOS runtimes have a concept of reporting back at the end of a render loop/frame after it has drawn onto the canvas/texture. We can provide an onAdvance
/ EventType.Advance
that you can hook into similarly if that might be of help here? It'll need to be added to the rive-wasm
web runtime first then propagated here.
Cool - will comment on this thread once that lands. Thanks for bringing this up!
@zplata thanks! Do you know the ETA for this? I can also try to contribute if you can point me to the best place to hook into the render loop
We should target having this change land downstream on rive-wasm this week - from there, it should be a quick update to React
@zplata while at this, is it possible to also add a hook to draw different elements during the canvas draw cycle? (Without having to ditch the whole React library and use the raw canvas lib)
I am imagining adding some hooks to mainAnimationCallback
function in animation_callback_handler
(https://github.com/rive-app/rive-wasm/blob/9bb60e900f3dcdcef0c8b6314fc3698a316a0c84/wasm/js/animation_callback_handler.js#L28)
like (super trivial example)
function mainAnimationCallback(time) {
// Snap off and reset the sub-callbacks first, since they might call requestAnimationFrame
// recursively.
const flushingSubCallbacks = _animationSubCallbacks;
_mainAnimationCallbackID = 0;
_lastAnimationSubCallbackID = 0;
_animationSubCallbacks = new Map();
// Invoke all pending animation callbacks.
flushingSubCallbacks.forEach((callback) => {
try {
callback(time);
} catch (err) {
console.error(err);
}
});
+ this.onFrameDraw(context); // pass anything else that could be useful
this.onAfterCallbacks();
if (_fpsCounter) {
_fpsCounter.frameComplete();
}
}
And consume it like
rive.onFrameDraw((ctx) => {
// draw other dynamic stuff outside of rive
ctx.beginPath();
...
if (... game logic ...) { ... }
})
Would love to leverage the existing React niceties like screen resize, fit, start/reset functions, and etc.
My use case here is drawing the mouse cursor location every frame to customize the look of the mouse within the canvas, and also check for collision detection.
Hi! Sorry for the delay - just as an update, we've landed the onAdvance
downstream, but will need a few more days to get a separately even lower-level cpp issue fixed up. Will make sure to release to React as soon as we've got that in.
Regarding your other comment, there isn't a straightforward way to hook into when individual elements draw. The mainAnimationCallback
is mainly for coordinating some offscreen canvases that might handle raster/mesh assets. You should be able to achieve what you're looking for however in the Rive editor using Rive Listeners (Pointer Move associated with a target node, and Pointer Enter for the node you want to have hit detection for). Here's a community example showing this: https://rive.app/community/4761-9624-maze-game/
@zplata Thanks for getting around to this.
i think the problem with pointer based events (whether within rive or within the code) is the events don't trigger until the mouse actually "moves".
E.g. https://rive.app/community/3571-7464-tunnel-dodger/ if you don't move your cursor at all, the collision detection actually won't get triggered even upon collision.
This is why I need to run the collision detection upon every frame render using a separate state to track the cursor position. With the onAdvance
hook I should be able to do this. If you have some other ideas on this it would be greatly appreciated!
Oh sorry, I totally dropped the ball on updating this thread - should be in v3.0.55+
!