Skip to content

Animations using after_draw() don't work properly #97

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

Closed
wants to merge 1 commit into from

Conversation

Neradoc
Copy link

@Neradoc Neradoc commented Jul 18, 2022

The Sparkle animation uses after_draw to setup the pixels currently being sparkled for the next frame, assuming show() will not be called until then. It also calls show() itself first to show the changes made in draw().

The problem is that animate() already calls show() after calling draw and after_draw. So the frame where the sparkle should show is actually "skipped": it only briefly appears instead of staying for a frame according to the speed parameter. The refactor from PR #23 changed the protocol where animations should no longer call show() themselves.

We can't change after_draw to be called after the call to show() in animate(), because it will break for example on animation groups using the same strip: if another animation triggers a show(), it will show the next frame of the sparkle prematurely. It also makes the protocol less predictable in general.

This PR drops after_draw() altogether and instead does everything in draw().

I don't think there is a need to preserve backwards compatibility with potential 3rd party animations using it, since it can't have worked properly since #23.

The Sparkle animation uses `after_draw` to setup the pixels currently being sparkled for the next frame, assuming `show()` will not be called until then. It also calls `show()` itself first to show the changes made in `draw()`.

The problem is that `animate()` already calls `show()` after calling draw and after_draw. So the frame where the sparkle should show is actually skipped and only briefly appears instead of staying for a frame according to the speed parameter. The refactor from PR adafruit#23 changed the protocol where animations should no longer call `show()` themselves.

We can't change `after_draw` to be called after the call to show() in animate(), because it will break on animation groups using the same strip. If another animation triggers a show() sooner, it will show the next frame of the sparkle prematurely. It also makes the protocol less predictable.
I have used `animate(False)`, followed by setting a pixel an calling `show()` for example to force the color of a single or a few pixels without going through the hassle of creating pixelmaps or groups (and also to simply make it look like it's superimposed over the animation).

So the solution would be to drop `after_draw` and instead memorize the previous list of pixels and set them back in the next draw.
@tekktrik tekktrik requested a review from a team July 18, 2022 03:01
@rhooper
Copy link

rhooper commented Jul 18, 2022

This looks good to me -- The only comment to add is that the show and immediate clear was intentional and might change the visual impact of some existing uses.

With the frame remaining set until the next interval, its more of a random pixel animation.
To achieve backwards comatibility, a flag could be added to init with a default of enabled.
The flag would determine whether .draw() should also clear the pixels it set immediately after a show().

@rhooper
Copy link

rhooper commented Jul 18, 2022

Oh, and I'm all for cleaning up the API!

@Neradoc
Copy link
Author

Neradoc commented Jul 18, 2022

Ah. I wasn't sure I understood how the animation works. We can close this then.

@Neradoc Neradoc closed this Jul 18, 2022
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

Successfully merging this pull request may close these issues.

2 participants