Adding decision document around new animation api#156
Conversation
✅ Deploy Preview for dsi-logo-maker ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
lucasdinonolte
left a comment
There was a problem hiding this comment.
I think this is a very nice proposal already. My only real remark would be that we should ship drawLoop utils a user can import when they are using the new customAnimation behavior. So they only need to write their own drawLoops if they really want to.
| export const handler = async ({ inputs, frame, done, useCanvas }) => { | ||
| const canvas = useCanvas(inputs.width, inputs.height); | ||
| let frameCount = 0; | ||
| const myDrawLoop = () => { |
There was a problem hiding this comment.
I like this. Maybe the drawloop could still just come as a helper from the core.
There was a problem hiding this comment.
I agree. That would be very nice!
| export const handler = async ({ inputs, frameCount, done }) => { | ||
| // drawing code | ||
| if (frameCount >= 100) { | ||
| done(svgString); |
There was a problem hiding this comment.
Just thinking about this. This forces users to keep svgString in a variable so it can either be returned or be send to done. While this isn't necessarily a problem as you have to the same using frame and done currently I think it might feel weird as return encourages to just build the return value there (at least to me).
So maybe the API could be simplified, that in animation mode done just flips a boolean in the engine that tells the engine to stop rendering after the next return value is received.
There was a problem hiding this comment.
I was actually just thinking about this. I think there's some weirdness around whether the user needs to pass something to the callbacks or not. So I like the idea of animation removing the need to do that and customAnimation requiring you to do that. We just need to keep in mind the difference that in animation mode, the done function will be called before the return, thus the last frame will not be recorded as a part of the animation, whereas it will be when you pass the string to the done function in customAnimation.
There was a problem hiding this comment.
Oh good point. So the logic should be
doneflips a boolean flag in the engine- the next return value is awaited
- the return value is passed on to mechanic.done to make sure the last frame is captured too
There was a problem hiding this comment.
That, or we change it so the done function never receives anything and always ends the animation immediately. That way, the signature for the frame and the done function will stay consistent, and the different modes are simply about whether you use the frame function or not. I think I like that slightly better.
| }; | ||
| ``` | ||
|
|
||
| The example above re-renders the component for every frame. If a user wants to use something like `react-spring` to speed up animation while keeping the frame-based approach, it could be done like this: |
There was a problem hiding this comment.
Just leaving this here to consider when implementing this:
I think the way the react engine currently works this would cause a re-render of everything every time, because the engine would call React DOM's render over and over again. When implementing this using the the new animation approach the engine should probably be re-build to render a wrapping component only once and then use a drawLoop within that parent component to re-render to function over and over again.
There was a problem hiding this comment.
Yes, I agree. We need to take advantage of the React render loop, so the component should not render from scratch using render every time. good point!
|
|
||
| ### `engine-p5` | ||
|
|
||
| For `engine-p5`, `mode` can only be set to `static` or `customAnimation`. Or perhaps we default both `animation` and `customAnimation` to the code below? |
There was a problem hiding this comment.
I like this. Maybe a descriptive info could be printed on the console, to educate developers about why the new animation isn't possible using p5
|
|
||
| The main disadvantage I can see is: | ||
|
|
||
| - Users who are not comfortable writing pure functions are now defaulted into this, and if they opt out, they need to write their own animation code. |
There was a problem hiding this comment.
I think this disadvantage can be mitigated by shipping animation loop utils for each engine that a user can just import into their function.
Co-authored-by: Lucas Nolte <hello@lucas-nolte.com>
|
Great! After thinking about it, I'm not a big fan of the |
| The new animation API comes with a few changes to the settings: | ||
|
|
||
| - The `animated` setting is renamed to `mode` (default: `static`) and the options are `static` (for static images), `animation` (for the new animation API) and `customAnimation` (for a user to implement their own animation code using the `frame` and `done` callbacks). | ||
| - `frameRate` (default: `60`) is a number that can be used to change the number of frames per second that the design function is called in `animation` mode. |
There was a problem hiding this comment.
Why only in animation mode?
Currently when creating video, we use a WebMWriter that receives a frameRate param. And that can be used on both modes, I think.
|
|
||
| ```js | ||
| export const handler = async ({ inputs, frameCount, done, useCanvas }) => { | ||
| const canvas = useCanvas(inputs.width, inputs.height); |
There was a problem hiding this comment.
I'm not sure I love the "use" prefix here. To me that's a React specific convention, and this specific example isn't React. I would try to expose arguments and functions that live in the same universe at the current engine.
| export const handler = async ({ inputs, frameCount, done, useCanvas }) => { | ||
| const canvas = useCanvas(inputs.width, inputs.height); | ||
| if (frameCount >= 100) { | ||
| done(canvas); |
There was a problem hiding this comment.
Maybe this is very engine specific, but does done have to receive the canvas? what happens with the one returned right after? I guess that's something that sticks out to me in this new way of writing design functions.
EDIT: now I see you commented on this too in another section. I agree with something like that should also be applied here.
Since they are strings anyways, I was thinking on going with |
|
Thanks @fdoflorenzano! I think both of those could work. If we keep the single |
|
I updated #152 with a draft implementation showing the new engine behavior for the two new animation modes. A few observations:
|
|
@fdoflorenzano I have edited the doc and I think it's ready for you to take a look :) |
|
@runemadsen I like it! A couple of thoughts came to mind:
|
You can read a nicer layout by visiting the markdown file directly.