Реализуйте эффект Таноса от 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; } }
Мы сделали это!
Вот ссылка для кода, если вы ее пропустили. ✨