Если вы хоть немного интересуетесь видеоиграми, вы, несомненно, знаете о Cyberpunk 2077. Это одна из самых ожидаемых игр 2020 года. Мир, который она рисует, имеет определенный стиль.
Эффект мерцающего шума при наведении курсора на сцену
Я принял вызов. Я копался, чтобы взглянуть на источник сайта. Немного покопавшись, я обнаружил, что это реализовано с помощью шейдеров и WebGL. Я совершенно новичок в написании шейдеров и WebGL. Это подтолкнуло меня попробовать. Но пока я отложил изучение кода WebGL и шейдеров на второй план.
Что привлекло наше внимание, когда я начал осматривать сайт в прямом эфире, так это аккуратные глючные кнопки эффектов. Я не новичок в создании глючных эффектов с помощью CSS. Мы решили, что я попытаюсь воссоздать их.
Мерцающая кнопка «ДОСТУПНО СЕЙЧАС»
И вот как вы можете это сделать!
Кнопка эффекта
Начнем с разметки:
Сначала нам нужно отсортировать размер, цвет и шрифт. Лучший способ сделать это правильно? Погрузитесь в источник и посмотрите, как это делается. При первом осмотре мы видим, что используется пользовательский шрифт. (Вы можете увидеть прямую ссылку на него в блоке кода ниже.)
Давайте создадим пользовательское правило @
@
src: url («https: //assets.codepen.io/605876/
}
Как только мы это сделаем, мы можем установить базовый стиль. Использование переменных CSS для таких вещей, как цвет и размер шрифта, даст нам дополнительные возможности позже. Это также является причиной использования цветового пространства HSL. Мы покажем, почему позже.
—primary: hsl (var (—
—
—
—
—color: hsl (0, 0%, 100%) ;
—
—
Объединив это, мы получаем отправную точку. Обратите внимание, как мы используем тень вставки вместо границы для этой синей линии? Это потому, что граница сбила бы наш текст с центра. Тень вставки не повлияет на выравнивание текста.
Обрезанный угол
Заметной особенностью кнопки является обрезанный угол. Моя первая мысль здесь — использовать путь клипа. Но, к моему удивлению, форма кнопок на сайте достигается фоновым изображением.
Мы можем обрезать угол, используя
Обратите внимание, что мы не обрезаем края кнопки. Мы даем кнопке 10% передышки. Это потому, что нам нужно учитывать тег «R25» и тот факт, что глючный эффект выходит за пределы кнопки. Это ловкий трюк с
Добавление этого к нашей кнопке дает нам желаемый эффект обрезки.
Создание тега R25
Далее давайте создадим тег «R25». Здесь мы могли бы найти псевдоэлемент и использовать его contentсвойство. Собственно, так это и делается на сайте. Но есть
aria-hidden class="cybr-btn__tag">R25
Чтобы стилизовать тег, мы можем указать его absoluteпозиционирование. Это требует от нас установки relativeпозиционирования на кнопке. Как и сама кнопка, тег использует inset
.
—
—
—
position: relative;
}
.
position: absolute;
padding: 1px 4px;
bottom: -5%;
right: 5%;
background: var (—
color: hsl (0, 0%, 0%) ;
}
Здесь мы ввели еще несколько переменных CSS. Хотя они используются тегом, мы разместили их под селектором кнопок. На это есть причина. Позже мы можем решить использовать возможности переменных с областью действия. Если мы это сделаем, нам нужно только установить переменные на селекторе кнопок. Если бы мы оставили переменные под правилом тегов, переменные, установленные на кнопке, не имели бы власти над нижней областью действия. Мы устанавливаем a
Теперь, когда наш тег на месте, кнопка обретает форму.
Добавление эффекта глюка
Настало время
красный фон
Обратите внимание, как синяя рамка следует за углом и огибает «R25»? Использование контура обрезки, как у нас, обрезает этот угол и не обрисовывает «R25». Реализация сайта использует файл
Использование фонового изображения позволит нам воссоздать эффект. Однако это сопряжено с некоторыми компромиссами, если мы хотим сделать наши кнопки гибкими и многоразовыми.
Например, что, если мы хотим изменить цвет кнопки? Нужно ли нам создавать много изображений для каждого варианта цвета кнопки? Что, если мы изменим соотношение сторон кнопки? Изображение больше не подходит.
Глючная анимация быстрая. Это достаточно быстро, поэтому маловероятно, что обрезанный угол будет заметен. Этот компромисс стоит того, чтобы получить более гибкий и повторно используемый набор стилей.
Давайте продолжим с этим решением. Мы можем добавить новый элемент для глюка. Для этого нужен тот же текст, что и для нашей кнопки, а также его нужно скрыть от программы чтения с экрана с помощью
aria-hidden class="cybr-btn__glitch">Glitch_
aria-hidden class="cybr-btn__tag">R25
Нам нужно продублировать текст здесь, и у нас есть варианты. На сайте используется псевдоэлемент для дублирования текста. Но если мы это делаем, то это означает анимацию сразу двух элементов для эффекта. Переместив текст в элемент glitch, нам нужно анимировать только один элемент:
.
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
}
Применение некоторых стилей, таких как
Но нас не устраивает эта обрезка углов. Кроме того, то, как мы используем
.
—clip: polygon (0 0, 100% 0, 100% 100%, 8% 100%, 0 70%) ;
}
.
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var (—primary) ;
}
Мы можем удалить
.
—border: 4px;
}
.
position: absolute;
top: calc (var (—border) * -1) ;
left: calc (var (—border) * -1) ;
right: calc (var (—border) * -1) ;
bottom: calc (var (—border) * -1) ;
background: var (—
}
.
content: '';
position: absolute;
top: calc (var (—border) * 1) ;
right: calc (var (—border) * 1) ;
bottom: calc (var (—border) * 1) ;
left: calc (var (—border) * 1) ;
background: var (—primary) ;
}
Затем мы можем повторно использовать клип для псевдоэлемента элемента сбоя. Хитрость в том, чтобы получить правильный элемент сбоя, состоит в том, чтобы расположить его абсолютно так, как если бы он был границей. Затем наложите псевдоэлемент поверх него. Применение одного и того же клипа к обоим элементам даст нам аккуратную синюю рамку, которая следует за углом.
Насколько это прикольно? Мы даже можем отрегулировать траекторию клипа, чтобы получить этот вырез вокруг «R25». Настройте
.
—clip: polygon (0 0, 100% 0, 100% 100%, 95% 100%, 95% 90%, 85% 90%, 85% 100%, 8% 100%, 0 70%) ;
}
.
position: absolute;
padding: 1px 4px;
bottom: -5%;
right: 5%;
color: hsl (0, 0%, 0%) ;
}
И здесь у нас есть возможность сделать
Два сложенных изображения
Если мы используем: beforeпсевдоэлемент для синего цвета нашей кнопки и: afterдля красного, а затем переведем: beforeпсевдоэлемент на размер границы, это даст нам границу. Это дает нам границу без применения border:
.
.
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.
background: var (—
transform: translate (var (—border), 0) ;
}
.
background: var (—primary) ;
}
Теперь у нас есть тень для тега и кнопки. И тег будет использовать фоновый цвет позади него. Попробуйте изменить на
Анимация кнопки
Почти готово! Подождите. У нас есть сбой. У нас есть все, что нам нужно. Осталось только анимировать кнопку на: hover.
Как происходит этот эффект глюка? Хитрость заключается в том, чтобы показать только элемент сбоя: hoverи по умолчанию применить к нему анимацию. Моим предположением здесь было использование transformи
Форсирование состояния в инспекторе
Затем проверьте стили и найдите анимацию. Нажмите на имя файла, и вы перейдете к источнику.
Исходный код анимации
Это позволило мне увидеть используемые ключевые кадры:
@keyframes
0% {
opacity: 1;
-
transform: translateZ (0) ;
-
}
2% {
-
-
transform: translate (-5px)
}
6% {
-
-
transform: translate (5px)
}
8% {
-
-
transform: translate (-5px)
}
9% {
-
-
transform: translate (0)
}
10% {
-
-
transform: translate3d (5px, 0,0)
}
13% {
-
-
transform: translateZ (0)
}
13.1% {
-
-
transform: translate3d (5px, 0,0)
}
15% {
-
-
transform: translate3d (5px, 0,0)
}
20% {
-
-
transform: translate3d (-5px, 0,0)
}
20.1% {
-
-
transform: translate3d (5px, 0,0)
}
25% {
-
-
transform: translate3d (5px, 0,0)
}
30% {
-
-
transform: translate3d (-5px, 0,0)
}
30.1% {
-
}
35% {
-
-
transform: translate (-5px)
}
40% {
-
-
transform: translate (5px)
}
45% {
-
-
transform: translate (-5px)
}
50% {
-
-
transform: translate (0)
}
55% {
-
-
transform: translate3d (5px, 0,0)
}
60% {
-
-
transform: translateZ (0) ;
opacity: 1
}
60.1% {
-
opacity: 1
}
to {
-
opacity: 1
}
}
Для нашей анимации мы можем следовать той же структуре. Но в нашем примере мы можем применить разные версии пути клипа:
.
—
—
—
—
—
—
—
—
}
@keyframes glitch {
0% {
}
2%, 8% {
transform: translate (calc (var (—
}
6% {
transform: translate (calc (var (—
}
9% {
transform: translate (0, 0) ;
}
10% {
transform: translate (calc (var (—
}
13% {
transform: translate (0, 0) ;
}
14%, 21% {
transform: translate (calc (var (—
}
25% {
transform: translate (calc (var (—
}
30% {
transform: translate (calc (var (—
}
35%, 45% {
transform: translate (calc (var (—
}
40% {
transform: translate (calc (var (—
}
50% {
transform: translate (0, 0) ;
}
55% {
transform: translate (calc (var (—
}
60% {
transform: translate (0, 0) ;
}
31%, 61%, 100% {
}
}
Это самая сложная часть для понимания. Что здесь происходит на самом деле? Наши ключевые кадры анимируют траекторию клипа на элементе сбоя. При этом покачиваем элемент из стороны в сторону. Мы можем замедлить анимацию, чтобы увидеть, что происходит.
Вот замедленная демонстрация, показывающая, как работает анимация:
И я также собрал демонстрацию, которая показывает различные состояния клипа:
Это значительно облегчило бы нам поддержку и настройку различных состояний анимации.
Соединение с наведением
Все, что осталось сделать, это привязать это к: hoverселектору. По умолчанию мы скрываем элемент глюка. Затем при наведении мы показываем его анимацию:
.
display: none;
}
.
display: block;
}
И это дает нам результат, который мы искали:
Заворачивать
И вот как вы воссоздаете кнопки Cyberpunk 2077, используя только CSS!
Помните, как мы использовали переменные для цветов? На то была причина. Комбинируя HSL с переменными, мы можем не только легко добавлять варианты цвета, но также можем добавить: activeизменение цвета.