CSS создает волновой эффект на кнопке (Ripple Animation).

CSS

Как отморозок CSS, на этот раз мне не терпелось попробовать его, увидев эффект клика на кнопке в библиотеке компонентов Vue.

Эффект выглядит так:

2018-08-26 13.20.35.gif

Во-первых, я наблюдал его первым и, вероятно, получил следующие характеристики:

  1. Возьмите положение, в котором нажата мышь, как начало координат, инекоторое значениеДиффузия по радиусу
  2. Есть градиенты по длине, ширине и прозрачности

Изначально это было реализовано на Vue, но если убрать реализацию фреймворка, придется пофилософствовать в JavaScript.Для этого я добился относительно простого эффекта.Эта статья в основном представляет собой построчное изложение и интерпретацию:

HTML-структура:

<button>
  <span class="background"></span>
  <span class="content">涟漪效果</span>
</button>

Излишне говорить, что эта кнопка состоит из контента и фона с волновым эффектом, контент в Vue<slot>входящий текст.

После этого грубо напишите несколько базовых стилей, которые имеют мало общего с кодом ядра анимации:

button {
  overflow: hidden;
  border: 1px solid #000;
  padding: 12px;
  cursor: pointer;
  position: relative;
  margin: 10px;
}

.content {
  position: relative;
  display: inline-block;
}

Чтобы достичь этого эффекта, мы в основном рассматриваем два момента, кратко изложенные выше: во-первых, как сделать одно место центральной точкой и распространить ее на обе стороны.

Чтобы получить положение мыши, мы используемevent.offsetXа такжеevent.offsetY, но если свет правильныйbackgroundВыполните абсолютное позиционирование, и достигнутый эффект представляет собой анимацию, начинающуюся с верхнего левого угла в качестве отправной точки.Чтобы стать центральной точкой, мы, естественно, подумали об этом.transform: translate(-50%, -50%), успешно преобразовал левый верхний угол в центральную точку.

Далее нам нужно определить радиус круга в анимации с учетомbuttonОбычно ширина > длины, поэтому берите ширину (button.clientWidth), чтобы сделать круг для радиуса.

Кроме того, мы хотим гарантировать, что щелчок мыши может заполнить любую область кнопки, поэтому ширина должна быть как минимум в 3 раза больше ее собственной.

В конечном счете, наши стили:

{
    left: event.offsetX + 'px',
    top: event.offsetY + 'px',
    width: button.clientWidth * 3 + 'px',
    height: button.clientWidth * 3 + 'px'
}

После того, как все приготовления завершены, используйтеtransitionАнимация нашей анимации:

transition: width 3s ease, height 3s ease, opacity 1s ease;

См. демонстрацию jsfiddle ниже для всего кода и эффектов:

Однако, если мы используем CSS Houdini, вся реализация анимации будет очень простой:

.ripple {
  --gradient: linear-gradient(to bottom right, deeppink, orangered);
  background: var(--gradient);
}
.ripple.animating {
  background: paint(ripple), var(--gradient);
}

Эффект виден:css-houdini.rocks/ripple/