title: How to replicate the Material Ripple animation in Vuejs?
body: <p>I am trying to replicate the ripple effect from Material Design since the current app I am working on is going to get rid of Quasar; so I'm building all the elements from the ground up.</p>
  <p><strong>This effect:</strong> <a href="https://i.stack.imgur.com/VKJIc.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VKJIc.gif" alt="enter image description here" /></a></p>
  <p>I've watched a few videos doing this in just pure CSS and JS and I've tried to convert it into my project, but am getting caught up somewhere. I have the hover effect and the mouse location logging properly, but the ripple effect is just not triggering and I don't know why.</p>
  <p>Any help would be greatly appreciated! Cheers!</p>
  <p><a href="https://codesandbox.io/s/practical-moore-h9nu5?file=/src/components/CButton.vue" rel="nofollow noreferrer"><strong>CodeSandbox Code</strong></a></p>
  <p><strong>CButton.vue</strong></p>
  <pre><code>&lt;template&gt;
    &lt;button
      @click=&quot;onClick&quot;
      :class=&quot;[
        'c-btn',
        `c-btn--${kind}`,
        disabled ? `_disabled` : '',
        kind === 'icon-round' ? 'shadow-5' : '',
      ]&quot;
    &gt;
      &lt;transition
        name=&quot;ripple&quot;
        @enter=&quot;rippleEnter&quot;
        @after-enter=&quot;afterRippleEnter&quot;
      &gt;
        &lt;span v-if=&quot;ripple&quot; ref=&quot;ripple&quot; class=&quot;ripple&quot; /&gt;
      &lt;/transition&gt;
      &lt;div class=&quot;_inner&quot;&gt;
        &lt;div class=&quot;_text&quot;&gt;
          &lt;slot&gt;{{ btnText }}&lt;/slot&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/button&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  export default {
    name: &quot;CcBtn&quot;,
    components: {},
    props: {
      btnText: { type: String },
      kind: { type: String, default: &quot;main&quot; },
      isBusy: { type: Boolean, default: false },
      /**
       * HTML5 attribute
       * @category state
       */
      disabled: { type: Boolean, default: false },
      color: { type: String, default: &quot;&quot; },
    },
    data() {
      return {
        ripple: false,
        x: 0,
        y: 0,
      };
    },
    methods: {
      onClick(e) {
        this.x = e.layerX;
        this.y = e.layerY;
        this.ripple = !this.ripple;
        console.log(`x`, this.x);
        console.log(`y`, this.y);
        console.log(`ripple`, this.ripple);
      },
      rippleEnter() {
        this.$refs.ripple.style.top = `${this.y}px`;
        this.$refs.ripple.style.left = `${this.x}px`;
      },
      afterRippleEnter() {
        this.ripple = false;
      },
    },
  };
  &lt;/script&gt;
  
  &lt;style lang=&quot;sass&quot; scoped&gt;
  .c-btn
    color: white
    padding: 10px 16px
    border-radius: 4px
    line-height: 1em
    min-height: 2em
    font-weight: bold
    font-size: 16px
    color: White
    cursor: pointer
    border: 1px solid transparent
    transition: background-color 0.5s
    ._inner
      display: flex
      align-items: center
      justify-content: center
    &amp;--main
      background: #9759ff
      min-width: 228px
      border-radius: 100px
      &amp;:hover
        background-color: lighten(#9759ff, 10%)
  
    &amp;--sub
      background: #f3eefe
      min-width: 228px
      border-radius: 100px
      color: black
      &amp;:hover
        background-color: darken(#f3eefe, 5%)
  
  .ripple
    display: block
    width: 20px
    height: 20px
    border-radius: 10px
    position: absolute
    top: 0
    left: 0
    pointer-events: none
    background-color: rgba(lighten(#9759ff, 20%), 0.8)
    opacity: 0
    transform: translate(-50%, -50%) scale(10)
    transition: opacity 0.4s ease-in-out, transform 0.4s ease-in-out
    &amp;-enter
      opacity: 1
      transform: translate(-50%, -50%) scale(0)
  &lt;/style&gt;
  </code></pre>
  <p><strong>App.vue</strong></p>
  <pre><code>&lt;template&gt;
    &lt;CButton :btnText=&quot;'Button'&quot; kind=&quot;main&quot; /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    &lt;CButton :btnText=&quot;'Button'&quot; kind=&quot;sub&quot; /&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import CButton from &quot;./components/CButton.vue&quot;;
  export default {
    name: &quot;App&quot;,
    components: {
      CButton,
    },
  };
  &lt;/script&gt;
  </code></pre>