How to create Ripple effect on Click - Material Design

后端 未结 10 1566
南旧
南旧 2020-12-12 11:17

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 ta

10条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-12 11:50

    CSS Paint API (introduced in 2018)

    The new CSS Paint API (part of the CSS "Houdini" draft) allows to write JavaScript functions to be used in CSS. Quote of the linked document:

    CSS Paint API allows you to programmatically generate an image whenever a CSS property expects an image. Properties like background-image or border-image are usually used with url() to load an image file or with CSS built-in functions like linear-gradient(). Instead of using those, you can now use paint(myPainter) to reference a paint worklet.

    This means you can implement a paint function in JavaScript and use it inside your CSS.

    Browser support (May 2019)

    Currently, only Chrome and Opera support the Paint API of the Houdini draft. Firefox has signaled "intent to implement". See ishoudinireadyyet.com or caniuse.com for more information.

    Code sample

    There is a working "ripple" example implemented by the Houdini task force available here. I extracted the "core" from the example below. It implements the custom paint function, adds custom CSS properties like --ripple-color and uses a JavaScript function to implement the animation and to start and stop the effect.

    Note, that it adds the custom paint function like this:

    CSS.paintWorklet.addModule('https://googlechromelabs.github.io/houdini-samples/paint-worklet/ripple/paintworklet.js');
    

    If you want to use the effect on your website, I recommend you download the file and reference it locally.

    // Adds the custom paint function
    CSS.paintWorklet.addModule('https://googlechromelabs.github.io/houdini-samples/paint-worklet/ripple/paintworklet.js');
    
    // the actual animation of the ripple effect
    function rippleEffect(element) {
      let start, x, y;
      element.addEventListener('click', function (evt) {
        this.classList.add('animating');
        [x, y] = [evt.offsetX, evt.offsetY];
        start = performance.now();
        const raf = (now) => {
          const tick = Math.floor(now - start);
          this.style.cssText = `--ripple-x: ${x}; --ripple-y: ${y}; --animation-tick: ${tick};`;
          if (tick > 1000) {
            this.classList.remove('animating');
            this.style.cssText = `--animation-tick: 0`;
            return;
          }
          requestAnimationFrame(raf);
        };
        requestAnimationFrame(raf);
      });
    }
    
    rippleEffect(document.querySelector('.ripple'));
    .ripple {
      font-size: 5em;
      background-color: rgb(0, 169, 244);
    
      /* custom property */
      --ripple-color: rgba(255, 255, 255, 0.54);
    }
    
    .ripple.animating {
      /* usage of the custom "ripple" paint function */
      background-image: paint(ripple);
    }

提交回复
热议问题