framer / motion

Open source, production-ready animation and gesture library for React
https://framer.com/motion
MIT License
22.27k stars 733 forks source link

[BUG] AnimatePresence - enter and exit animations are mixed when they alternate rapidly #2618

Open Thanaen opened 1 month ago

Thanaen commented 1 month ago

1. Read the FAQs 👇 Done ✅

2. Describe the bug Enter and exit animations are mixed when they alternate rapidly.

3. IMPORTANT: Provide a CodeSandbox reproduction of the bug https://stackblitz.com/edit/vitejs-vite-5ocwzr?file=src%2FApp.tsx

4. Steps to reproduce

  1. Slow click on "Next" and "Previous" to see the animation properly working
  2. Now quickly click on "Next" and "Previous" to see the animation break

5. Expected behavior

The animation that works when slowly clicking on "Next" and "Previous" should also work when quickly clicking on "Next" and "Previous"

6. Video or screenshots framer-presence-issue

If applicable, add a video or screenshots to help explain the bug.

7. Environment details Tested on:

Tested on both framer-motion@^10 (currently 10.18.0) & framer-motion@^11 (currently 11.0.28)

UPDATE: The problem doesn't actually exist on 10.18.0, even though this version has a small glitch visual (it blinks) when you make a quick change.

Thanaen commented 1 month ago

PS: This is possibly a duplicate of bug #2554 , but the work-around proposed in this bug (use framer-motion@11.0.10) does not solve the problem in my repro repository.

Thanaen commented 1 month ago

After analysis, it would appear that you end up with both elements systematically in the DOM when you quickly do the "Next" / "Previous", which corresponds to the situation in the other bug mentioned.

beefchimi commented 2 weeks ago

I have also been battling with this issue for awhile, and have not found a fix.

While I am unable to reproduce the issue in the StackBlitz link provided by the author, I can consistently re-create it in several of my local projects.

Here is a video of a TextArea UI animating some "invalid character count" UI. We can see that the UI animates in/out perfectly when making edits at a moderate pace. But once I start making edits more quickly - such as removing and re-adding the e - the "invalid UI" gets stuck and remains visible even after the conditions that would render it are no longer true.

https://github.com/framer/motion/assets/643944/009dc9d6-74d3-4828-89c7-9c970870545f

The code for this would look something like:

const characterCountMarkup = !validateUsernameLength(value) ? (
    <CharacterCount key={`UserName-CharacterCount-${value.length}`} count={value.length} />
) : null;

<AnimatePresence>{characterCountMarkup}</AnimatePresence>

I am currently on version 11.1.7 but have tried this on 11.0 as well with the same result.

As indicated by OP, there appear to be several issues raising this same concern: https://github.com/framer/motion/issues/2554 and https://github.com/framer/motion/issues/2462

beefchimi commented 2 weeks ago

I've created another minimal reproduction in case it is helpful: https://stackblitz.com/edit/framer-motion-fast-change-bug?terminal=dev

https://github.com/framer/motion/assets/643944/ca6ec126-db3b-43f7-bc4b-2550615b1248

As discovered in the other threads... opacity seems to be the culprit in causing this bug. I've forked my reproduction above to use a translate animation, and it appears to work without issue: https://stackblitz.com/edit/framer-motion-fast-change-bug-workaround?terminal=dev

However... for my specific needs, I do in fact need an opacity animation.

Thanaen commented 2 weeks ago

@beefchimi Not using opacity reduces the problem, but doesn't solve it entirely (link to my own comment 😄: https://github.com/framer/motion/issues/2554#issuecomment-2066629659)

Taib-Rabah commented 4 days ago

I also faced that problem, I had to prevent the user from changing the state rapidly by disabling the buttons while the animation is running

here's what I created if any1 is interested: