angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.23k stars 6.7k forks source link

Icon buttons can accrue excessive ripple effects #8838

Closed thw0rted closed 6 years ago

thw0rted commented 6 years ago

Bug, feature request, or proposal:

Bug

What is the expected behavior?

Clicking or touching an icon button should show one ripple that disappears promptly

What is the current behavior?

Multiple rapid clicks can create stacked ripple effects that dissipate slowly

What are the steps to reproduce?

Open the button docs and rapidly click one of the icon buttons. Observe that the ripple effect grows very dark as multiple mat-ripple-element elements are created and attached to the mat-button-ripple. In a poor performance situation (slow system, patchy browser animation support, lots of background activity) this can be especially noticeable as each ripple takes multiple seconds to remove itself.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Impacts docs page as of today, so I think that's 5.0.0-rc3? It seems to me that the fade out animation is choppier in Firefox than Chromium (and thus the stacking effect is more apparent).

Is there anything else we should know?

Just having the ripples stack isn't such a big deal, but I have a page that's doing intensive background work and it can easily see one or more ripples stick around for over 5 seconds, which is pretty confusing for the user. I think probably it makes sense to limit each button to a single ripple, but I don't have a cite from the spec to back me up.

devversion commented 6 years ago

I'm not really able to see the issue on my setup. In regards to 5.0.0-rc.3, the stacking animation and fade-out animation hasn't been updated recently.

It might be something that really depends on the environment and background activity and has been there in the last releases too. Also I'm not sure whether this is reason to limit the ripples to one per button.

Would it be possible to get a video that shows the problem in your background-intensive application?

thw0rted commented 6 years ago

This example shows a mat-icon-button that triggers a mat-menu (while graphically-intensive stuff is happening out of frame).

Menu example

As you can see, I'm opening and closing the menu multiple times consecutively, which hopefully the user wouldn't do, but it highlights the stacking effect. Note that the GIF shows the ripples finally going away in real time -- it's a good 2 or 3 seconds after I close the menu for the last time before the last ripple disappears in the video, and it can be even worse that that sometimes in browser.

thw0rted commented 6 years ago

I'm not sure what's causing the ripples to hang around, but I just noticed that this is also impacting FABs -- on click the button gets a shade lighter, which also stacks, so in this same application, clicking a FAB repeatedly makes it get progressively closer to white. What's particularly bad is that this does not change the button's foreground color to match the correct contrast for the theme, given the lighter background color.

Maybe instead of refactoring to only ever have one ripple, we could figure out why the ripple / overlay is taking so long to go away? My particular application is not open source but I could probably make a quick repro using similar components, if need be.

devversion commented 6 years ago

I'm not really sure I see the problem. If you mean, that too much ripples overlap and the text is more unreadable, I wouldn't really consider this an issue.

If someone really triggers a lot of ripples, then the overlapping of the individual ripples shouldn't affect the overall reading experience, because it doesn't seem to be the intention to read the text.

thw0rted commented 6 years ago

The concern is less that the text is unreadable and more that it's confusing to the user when ripples persist for multiple seconds. They might think, "Why does that button look different from the others? Is it 'highlighted' or 'active' in some way?"

I'm increasingly thinking that maybe the real issue to work out is why it can take several seconds for ripples to dissipate when I would expect them to finish animating in more or less constant time. My first thought was to limit ripples to one per component, but that would only mask the symptoms. I guess the complaint I'd like to see addressed is, ripples should never be visible for more than a (very?) short time after user action.

Is the ripple effect designed to finish in (approximately) constant time, or is it trying to show a fixed number of animation steps, regardless of how long they take to display? If the latter, is there a reason that decision was made? Is there a workaround to get through the animation quickly if, for whatever reason, the current implementation is taking too long?

devversion commented 6 years ago

To answer your question, yeah the ripples are designed to finish in a constant time. By default 450ms to fade-in and 400ms to fade-out.

You are able to globally affect the fade-in duration (only), by using the the RippleGlobalOptions as described in this markdown file

thw0rted commented 6 years ago

Would you have any idea why the animations might take several seconds to finish instead? I believe the GIF a few comments up this thread is in real time, so maybe 4-5 seconds total after several clicks...

devversion commented 6 years ago

I can see what you mean in the GIF, but I'm not really sure if those are the ripples. If I try to reproduce this in one of our matMenu examples, I'm not really able to see such a behavior. If the menu closes, the button that opened the menu, will be re-focused automatically (for accessibility purposes) and it kind of looks similar to ripples.

The ripples should really fade-out in the specified amount of time. If that's not the case, then something might still have the button pressed (mousedown, but no mouseup).

Do you think, you would be able to make another GIF, using the docs example? https://material.angular.io/components/menu/overview Thanks in advance.

thw0rted commented 6 years ago

I'm trying to stress out the browser enough to get the 4+ second delays illustrated in the GIF but I'm having trouble reproducing too. I embedded an iFrame with a WebGL stress test that really taxes rendering on the tab:

<iframe src="https://webglsamples.org/aquarium/aquarium.html" style="width:600px;height:480px;"></iframe>

While the menu animations do become choppy, the ripples still get removed within a second or so.

Is it possible that ripple behavior was updated in the last couple releases? I'm noticing the improved behavior in my application as well (currently on 5.0.2) It might be fixed, or at least improved enough to close the issue. Sorry to take so much of your time!

devversion commented 6 years ago

That's a good idea (trying to stress the browser). Regarding improvements to the ripples: there was no real improvement in the last releases. We added passive event listeners recently, but those are not released yet.

devversion commented 6 years ago

I'm going to close this issue, because actually everything is working as expected. The active element of the menu will have it's focus restored, and that causes the "look-alike" ripple on the button.

With this PR: https://github.com/angular/material2/pull/9303, the focus effect for menus after closing with mouse shouldn't appear anymore.

angular-automatic-lock-bot[bot] commented 4 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.