topleft topleft - 6 months ago 52
Javascript Question

How to create Ripple effect - Material Design

I'm new to CSS animations and I've been trying to make their animation work for the last hours by looking at their code, but I can't make it work for now.

I'm talking about this effect: https://angular.io/ (menu effect).
Basically, it's an animation on click that spreads a circle from the mouse cursor.

Seems it comes down to these 2 lines:

transition: box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),-webkit-transform .4s cubic-bezier(.25,.8,.25,1);
transition: box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),transform .4s cubic-bezier(.25,.8,.25,1);


PS: Maybe there's some jQuery I didn't see.

Answer

I have used this sort of code before on a few of my projects.

Using jQuery we can position the effect to its not just static and then we add the span element onclick. I have added comments so it makes it easier to follow.

Demo Here

jQuery

$("div").click(function (e) {

  // Remove any old one
  $(".ripple").remove();

  // Setup
  var posX = $(this).offset().left,
      posY = $(this).offset().top,
      buttonWidth = $(this).width(),
      buttonHeight =  $(this).height();

  // Add the element
  $(this).prepend("<span class='ripple'></span>");


 // Make it round!
  if(buttonWidth >= buttonHeight) {
    buttonHeight = buttonWidth;
  } else {
    buttonWidth = buttonHeight; 
  }

  // Get the center of the element
  var x = e.pageX - posX - buttonWidth / 2;
  var y = e.pageY - posY - buttonHeight / 2;


  // Add the ripples CSS and start the animation
  $(".ripple").css({
    width: buttonWidth,
    height: buttonHeight,
    top: y + 'px',
    left: x + 'px'
  }).addClass("rippleEffect");
});

CSS

.ripple {
  width: 0;
  height: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.4);
  transform: scale(0);
  position: absolute;
  opacity: 1;
}
.rippleEffect {
    animation: rippleDrop .6s linear;
}

@keyframes rippleDrop {
  100% {
    transform: scale(2);
    opacity: 0;
  }
}