Реализуйте эффект Таноса от Google без дополнительной библиотеки JS или фреймворка.

Я думаю, что это очень интересный эффект, несмотря на то, что автоматическая прокрутка — это своего рода игнорирование.

Взгляните на инструмент разработчика Chrome: видно, что div все еще здесь.

Версия для настольных ПК использует пакет html2canvas для достижения эффекта фильтрации, но мобильная версия, похоже, использует более простой подход.

Я продемонстрирую свой мыслительный процесс и то, как создать аналогичный эффект самостоятельно.

Давайте начнем!

Мы не хотим слишком усложнять это. Я полностью создам его на codepen без использования каких-либо библиотек или фреймворков. Итак, у нас есть только 3 файла: html, CSS и JS.

Вы можете посмотреть мой окончательный результат здесь.

Сначала я создаю кнопку и блок, чтобы было что пропадать 😂

В HTML:

<button type="button" class="btn" onclick="onBtnClick();" id="btn">Snap</button>
    <div class="block div-show" id="block">
      Good bye, the cruel world
      <br>
      Hello, the new world
    </div>
  </div>
</div>

Примените некоторые базовые стили к кнопке и блоку, чтобы придать им вид карточки Google.

В CSS:

body {
  font-size: 16px;
}
.btn,
.block {
  text-align: center;
  border: 1px solid transparent;
}
.btn {
  margin: 8px auto;
  padding: 6px 12px;
  background-color: #5bc0de;
  color: white;
  display: inline-block;
  border-radius: 3px;
  cursor: pointer;
}
.btn:hover {
  background-color: #1490ac;
}
.block {
  width: 600px;
  height: 200px;
  border-color: #cfd8dc;
  border-radius: 8px;
  box-shadow: none;
  padding: 12px;
  line-height: 40px;
}

Добавьте обработчик события кнопки в JS:

Я пишу служебную функцию для поиска и замены имени класса. Вы можете использовать Element.classList , но у него нет кроссбраузерной поддержки. Старая история, IE и Safari… 🤦‍♂️

// a utility function help to find class list
function classHas(base, has) {
  const arr = base.split(" ")
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === has) 
      return true;
  }
}
function onBtnClick() {
  const block = document.getElementById("block");
  const btn = document.getElementById("btn");
  console.log(block.innerHTML);
}

Когда я нажимаю кнопку, я хочу, чтобы блок исчез. Нажмите еще раз, он появится. Вот и все.

Я достигаю этого, переключая имя class в блоке div.

В CSS

.div-hidden {
  transition: opacity 1.75s ease 0s;
  opacity: 0;
  visibility: hidden;
}
.div-show {
  transition: opacity 1.5s ease 0s;
  opacity: 1;
  visibility: visible;
}

In js

// a utility function help to replace the class list
function classReplace(base, replace, next) {
  return base.replace(replace, next)
}
function onBtnClick() {
  const block = document.getElementById("block");
  const btn = document.getElementById("btn");
if (classHas(block.className, "div-show")) {
    block.className = classReplace(block.className, "div-show", "div-hidden")
    btn.innerHTML = "Show"
  } else {
    block.className = classReplace(block.className, "div-hidden", "div-show")
    btn.innerHTML = "Snap"
  }
}

Готово!

Подождите секунду... Эффект исчезновения не размыт. Это не сила Таноса! 😈

В эффекте Google карта растворяется горизонтально, прежде чем исчезнуть.

Как это сделать?

Мы можем сделать так, чтобы 2 одинаковые карточки с одинаковым содержанием перекрывали друг друга. Когда они исчезают, один движется влево, а другой вправо.

Но мы также хотим сохранить позицию карты, когда она вернется… 🤔

Мое решение состоит в том, чтобы сохранить исходную карту на месте. При «Snap» мы делаем 2 копии оригинальной карты, прячем оригинальную карту и позволяем этим 2 делать анимацию растворения.

Чтобы применить позицию abosolute к дубликатам, я добавляю контейнер для нашего основного контента.

В html заменяем block на:

<div class="block-container">
  <div id="block" class="div-show block-main">
    <div class="block">
      Good bye, the cruel world
      <br>
      Hello, the new world
    </div>
  </div>
  <div id="overlay"></div>
</div>

<div id=”overlay”></div> будет заполнителем для дубликатов.

Добавление анимации и абсолютного положения в CSS. Мы устанавливаем block-container на position: relative; в качестве эталона для оверлейных карт.

В CSS:

.block-container {
  position: relative;
  margin: 8px 0;
}
.div-overlay {
  position: absolute;
  top: 0;
  animation-iteration-count: 1;
  animation-duration: 1.5s;
  visibility: hidden;
}
.div-overlay-left {
  animation-name: slide-left;
}
.div-overlay-right {
  animation-name: slide-right;
}
@keyframes slide-left {
  from {
    left: 0;
    opacity: 1;
    visibility: visible;
  }
  to {
    left: -30px;
    opacity: 0;
  }
}
@keyframes slide-right {
  from {
    left: 0;
    opacity: 1;
    visibility: visible;
  }
  to {
    left: 30px;
    opacity: 0;
  }
}

Мы копируем innerHTML из нашего исходного блока, делаем две его копии и применяем анимацию движения влево и вправо к каждой из них.

In JS:

function onBtnClick() {
  const block = document.getElementById("block");
  const btn = document.getElementById("btn");
  const overlay = document.getElementById("overlay");
if (classHas(block.className, "div-show")) {
    block.className = classReplace(block.className, "div-show", "div-hidden")
    btn.innerHTML = "Show"
    const content = block.innerHTML;
    overlay.innerHTML = "<div class=\"div-overlay div-overlay-left\">" + content + "</div>" + "<div class=\"div-overlay div-overlay-right\">" + content + "</div>";
  } else {
    block.className = classReplace(block.className, "div-hidden", "div-show")
    btn.innerHTML = "Snap"
    overlay.innerHTML = null;
  }
}

Мы сделали это!

Вот ссылка для кода, если вы ее пропустили. ✨