DEV Community

Cover image for Recreating the material design ripple effect in React

Recreating the material design ripple effect in React

Rohan Faiyaz Khan on December 18, 2019

Cover image by Linus Nylund on Unsplash Link to original post my blog Rippling in React We have all seen the ripple effect animation w...
Collapse
 
dustinkiselbach profile image
dustinkiselbach

This looks great and works well. Thank you. Is it possible to register onclick events through the ripple container? I would like to be able to click through the container so that I can register specific onclick functions to different components behind the ripple container.

Collapse
 
rohanfaiyazkhan profile image
Rohan Faiyaz Khan

Hi thank you for the response! I am not sure what you mean by clicking through the ripple container. I wasn't initially envisioning any other components inside it. Can you give me an example of what you are trying to do?

Collapse
 
dustinkiselbach profile image
dustinkiselbach

Basically I would like to have the ripple effect over an entire component, with sub components inside with different onclick functions. Would this be possible?

Thread Thread
 
rohanfaiyazkhan profile image
Rohan Faiyaz Khan

Oh yeah absolutely. You actually don't need to nest the children inside the ripple in that case. You would do something like this:

<ParentComponent>
   <ChildButton onClick={someHandler} />
   <Ripple />
</ParentComponent>

You might want to be a little concious of the event bubbling if you are using this approach.

Thread Thread
 
dustinkiselbach profile image
dustinkiselbach

Thanks so much!

Collapse
 
sannajammeh5 profile image
Sanna Jammeh • Edited

Solid guide, however there is a mistake in your code! You are setting the rippleArray with newRippleArray which is an Object. Therefore the map method is never called. You must change setRippleArray(newRipple) to setRippleArray(prevState => [...prevState, newRipple]);

Also debouncer callback is never called because you immediately return the clearTimeout, not a function that calls clearTimeout.

Change useLayoutEffect(fn..., return clearTimeout(bounce), [...]); to useLayoutEffect(fn..., return () => clearTimeout(bounce), [...];

Collapse
 
rohanfaiyazkhan profile image
Rohan Faiyaz Khan

Thank you so much for catching that. Fixed it.

Collapse
 
sanishkr profile image
sanish • Edited

Thanks for making this. This is working perfectly except when I have a lot elements having ripple effect and it shows animation only for elements which are visible above the fold. Once I scroll down, animation doesn't seem to be visible. Can you please look into this

Collapse
 
dustinkiselbach profile image
dustinkiselbach

I had the same issue. In the addRipple function, where const x is defined add - window.scrollX at the end, and - window.scrollY where const y is defined at the end. That should fix your problem.

Collapse
 
sanishkr profile image
sanish

Thanks for quick reply. I tried your approach, it worked. I also tried to replace event.pageX and event.pageY with event.clientX and event.clientY. Both works!!

Collapse
 
leireriel profile image
Leire Rico

Thank you Rohan! I followed your guide and implemented the effect for my side project :)

Collapse
 
rohanfaiyazkhan profile image
Rohan Faiyaz Khan

Glad to hear you found it useful!

Collapse
 
abdulateefmuhammad profile image
Abdulateef Mohammed Al-radaee

A pro article I learnt alot not about ripple workaround and also the way create a component of react.
thanks a lot.