Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
227 views
Welcome To Ask or Share your Answers For Others

1 Answer

Ripple effect in Material Design using jQuery and CSS3

Click Ripple Google material design

To create a UX Ripple effect basically you need to:

  • append to any element an oveflow:hidden element to contain the ripple circle (you don't want to alter your original element overflow, neither see the ripple effect go outside of a desired container)
  • append to the overflow container the ripple wave translucent radial element
  • get the click coordinates and CSS3 animate the scaling and opacity of the ripple element
  • Listen for the animationend event and destroy the ripple container.

The basic code:

Basically add data-ripple (default as white ripple) or data-ripple="#000" to a desired element:

<a data-ripple> EDIT </a>
<div data-ripple="rgba(0,0,0, 0.3)">Lorem ipsum</div>

CSS:

/* MAD-RIPPLE EFFECT */
.ripple{
  position: absolute;
  top:0; left:0; bottom:0; right:0;
  overflow: hidden;
  -webkit-transform: translateZ(0); /* to contain zoomed ripple */
  transform: translateZ(0);
  border-radius: inherit; /* inherit from parent (rounded buttons etc) */
  pointer-events: none; /* allow user interaction */
          animation: ripple-shadow 0.4s forwards;
  -webkit-animation: ripple-shadow 0.4s forwards;
}
.rippleWave{
  backface-visibility: hidden;
  position: absolute;
  border-radius: 50%;
  transform: scale(0.7); -webkit-transform: scale(0.7);
  background: rgba(255,255,255, 1);
  opacity: 0.45;
          animation: ripple 2s forwards;
  -webkit-animation: ripple 2s forwards;
}
@keyframes ripple-shadow {
  0%   {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
  20%  {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
  100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@-webkit-keyframes ripple-shadow {
  0%   {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
  20%  {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
  100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@keyframes ripple {
  to {transform: scale(24); opacity:0;}
}
@-webkit-keyframes ripple {
  to {-webkit-transform: scale(24); opacity:0;}
}

jQuery

jQuery(function($) {

  // MAD-RIPPLE // (jQ+CSS)
  $(document).on("mousedown", "[data-ripple]", function(e) {
    
    var $self = $(this);
    
    if($self.is(".btn-disabled")) {
      return;
    }
    if($self.closest("[data-ripple]")) {
      e.stopPropagation();
    }
    
    var initPos = $self.css("position"),
        offs = $self.offset(),
        x = e.pageX - offs.left,
        y = e.pageY - offs.top,
        dia = Math.min(this.offsetHeight, this.offsetWidth, 100), // start diameter
        $ripple = $('<div/>', {class : "ripple",appendTo : $self });
    
    if(!initPos || initPos==="static") {
      $self.css({position:"relative"});
    }
    
    $('<div/>', {
      class : "rippleWave",
      css : {
        background: $self.data("ripple"),
        width: dia,
        height: dia,
        left: x - (dia/2),
        top: y - (dia/2),
      },
      appendTo : $ripple,
      one : {
        animationend : function(){
          $ripple.remove();
        }
      }
    });
  });

});

Here's a full-featured demo:

jQuery(function($) {

  // MAD-RIPPLE // (jQ+CSS)
  $(document).on("mousedown", "[data-ripple]", function(e) {
    
    var $self = $(this);
    
    if($self.is(".btn-disabled")) {
      return;
    }
    if($self.closest("[data-ripple]")) {
      e.stopPropagation();
    }
    
    var initPos = $self.css("position"),
        offs = $self.offset(),
        x = e.pageX - offs.left,
        y = e.pageY - offs.top,
        dia = Math.min(this.offsetHeight, this.offsetWidth, 100), // start diameter
        $ripple = $('<div/>', {class : "ripple",appendTo : $self });
    
    if(!initPos || initPos==="static") {
      $self.css({position:"relative"});
    }
    
    $('<div/>', {
      class : "rippleWave",
      css : {
        background: $self.data("ripple"),
        width: dia,
        height: dia,
        left: x - (dia/2),
        top: y - (dia/2),
      },
      appendTo : $ripple,
      one : {
        animationend : function(){
          $ripple.remove();
        }
      }
    });
  });

});
*{box-sizing:border-box; -webkit-box-sizing:border-box;}
html, body{height:100%; margin:0;}
body{background:#f5f5f5; font: 14px/20px Roboto, sans-serif;}
h1, h2{font-weight: 300;}


/* MAD-RIPPLE EFFECT */
.ripple{
  position: absolute;
  top:0; left:0; bottom:0; right:0;
  overflow: hidden;
  -webkit-transform: translateZ(0); /* to contain zoomed ripple */
  transform: translateZ(0);
  border-radius: inherit; /* inherit from parent (rounded buttons etc) */
  pointer-events: none; /* allow user interaction */
          animation: ripple-shadow 0.4s forwards;
  -webkit-animation: ripple-shadow 0.4s forwards;
}
.rippleWave{
  backface-visibility: hidden;
  position: absolute;
  border-radius: 50%;
  transform: scale(0.7); -webkit-transform: scale(0.7);
  background: rgba(255,255,255, 1);
  opacity: 0.45;
          animation: ripple 2s forwards;
  -webkit-animation: ripple 2s forwards;
}
@keyframes ripple-shadow {
  0%   {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
  20%  {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
  100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@-webkit-keyframes ripple-shadow {
  0%   {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
  20%  {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
  100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@keyframes ripple {
  to {transform: scale(24); opacity:0;}
}
@-webkit-keyframes ripple {
  to {-webkit-transform: scale(24); opacity:0;}
}


/* MAD-BUTTONS (demo) */
[class*=mad-button-]{
  display:inline-block;
  text-align:center;
  position: relative;
  margin: 0;
  white-space: nowrap;
  vertical-align: middle;
  font-family: "Roboto", sans-serif;
  font-size: 14px;
  font-weight: 500;
  text-transform: uppercase;
  text-decoration: none;
  border: 0; outline: 0;
  background: none;
  transition: 0.3s;
  cursor: pointer;
  color: rgba(0,0,0, 0.82);
}
[class*=mad-button-] i.material-icons{
  vertical-align:middle;
  padding:0;
}
.mad-button-raised{
  height: 36px;
  padding: 0px 16px;
  line-height: 36px;
  border-radius: 2px;
  box-shadow: /*amb*/ 0 0   2px rgba(0,0,0,0.15),
    /*key*/ 0 1px 3px rgba(0,0,0,0.25);
}.mad-button-raised:hover{
  box-shadow: /*amb*/ 0 0   2px rgba(0,0,0,0.13),
    /*key*/ 0 2px 4px rgba(0,0,0,0.2);
}
.mad-button-action{
  width: 56px; height:56px;
  padding: 16px 0;
  border-radius: 32px;
  box-shadow: /*amb*/ 0 0   2px rgba(0,0,0,0.13),
    /*key*/ 0 5px 7px rgba(0,0,0,0.2);
}.mad-button-action:hover{
  box-shadow: /*amb*/ 0 0   2px rgba(0,0,0,0.11),
    /*key*/ 0 6px 9px rgba(0,0,0,0.18);
}
[class*=mad-button-].mad-ico-left  i.material-icons{ margin: 0 8px 0 -4px; }
[class*=mad-button-].mad-ico-right i.material-icons{ margin: 0 -4px 0 8px; }

/* MAD-COLORS */
.bg-primary-darker{background:#1976D2; color:#fff;}
.bg-primary{ background:#2196F3; color:#fff; }
.bg-primary.lighter{ background: #BBDEFB; color: rgba(0,0,0,0.82);}
.bg-accented{ background:#FF4081; color:#fff; }

/* MAD-CELL */
.cell{padding: 8px 16px; overflow:auto;}
<link href='https://fonts.googleapis.com/css?family=Roboto:500,400,300&amp;subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>

<div class="cell">
  <button data-ripple class="mad-button-raised mad-ico-left bg-primary"><i class="material-icons">person</i>User settings</button>
  <a data-ripple href="#" class="mad-button-action bg-accented"><i class="material-icons">search</i></a>
</div>

<div data-ripple class="cell bg-primary-darker">
  <h1>Click to Ripple</h1>
  <p>data-ripple</p>
</div>

<div data-ripple="rgba(0,0,0, 0.4)" class="cell bg-primary">
  <p>data-ripple="rgba(0,0,0, 0.4)"</p>
  <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore....</p>
  <p><a data-ripple class="mad-button-raised mad-ico-right bg-accented">Edit<i class="material-icons">edit</i></a></p>
</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...