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
Adding decision document around new animation api #156
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for dsi-logo-maker ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
decisions/01-new-animation-api.md
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this. Maybe the drawloop could still just come as a helper from the core.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. That would be very nice!
decisions/01-new-animation-api.md
Outdated
export const handler = async ({ inputs, frameCount, done }) => { | ||
// drawing code | ||
if (frameCount >= 100) { | ||
done(svgString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh good point. So the logic should be
done
flips 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed
decisions/01-new-animation-api.md
Outdated
}; | ||
``` | ||
|
||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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!
decisions/01-new-animation-api.md
Outdated
|
||
### `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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
decisions/01-new-animation-api.md
Outdated
|
||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this disadvantage can be mitigated by shipping animation loop utils for each engine that a user can just import into their function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed!
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
decisions/01-new-animation-api.md
Outdated
|
||
```js | ||
export const handler = async ({ inputs, frameCount, done, useCanvas }) => { | ||
const canvas = useCanvas(inputs.width, inputs.height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
decisions/01-new-animation-api.md
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.