1. Введение
В этом выпуске я поделюсь тем, как использовать только CSS3 для достижения динамических солнечных, облачных, дождливых и снежных условий в одном теге. Технические ключевые моменты — «один тег» и «чистый CSS». Давайте посмотрим на окончательный эффект:
Взгляните еще раз на HTML-код:<!--晴-->
<div class="weather sunny"></div>
<!--阴-->
<div class="weather cloudy"></div>
<!--雨-->
<div class="weather rainy"></div>
<!--雪-->
<div class="weather snowy"></div>
Правильно, это так самовольно, у каждой анимации есть метка, а картинок и JS нет! Техническая реализация подробно описана ниже.
Основные задействованные свойства CSS3:
- Преобразование: используется для сдвига, вращения, эффектов масштабирования.
- box-shadow: использовать проекцию для репликации изображений (ключ!)
- clip-path: замаскировать элемент на основе нарисованной формы
- анимация: установить анимацию элемента
И наиболее критическое использование псевдоэлементов :before и :after для достижения единого тега.
Что я могу узнать из этого обмена?
Самое главное: альтернативный геймплей box-shadow — «теневой клон».
Давайте начнем объяснять один за другим.
2 Основной фон
Область фона синего блока на картинке очень простая, поэтому нет необходимости говорить о ней.
Задаются ширина и высота, цвет фона и закругленные углы области.
.weather {
position: relative;
display: inline-block;
width: 180px;
height: 240px;
background: #23b7e5;
border-radius: 8px;
}
3 солнечно
Значок солнечного дня состоит из двух элементов: солнца и внутреннего шестиугольника солнца.
Два псевдоэлемента :before и :after могут «добавлять» элемент внутрь элемента, для чего они и используются.
3.1 Рисование солнца
Во-первых, реализуйте солнце с помощью :before.
.sunny:before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
background: #F6D963;
border-radius: 50%;
box-shadow: 0 0 20px #ff0;
z-index: 2;
}
content используется для создания элемента.
position, top, left и transform используются для центрирования.
Box-shadow реализует эффект внешнего освещения, что является самым простым и наиболее часто используемым способом использования box-shadow.
3.2 Рисование внутреннего шестиугольника
Используйте :after для внутренних шестиугольников.
Ключом к этому является использование масок. Нарисуйте внутренний шестиугольник с помощью clip-path. Это становится простой задачей по геометрии для младших классов средней школы.
Внутренний шестиугольник состоит из двух равносторонних треугольников.
После слияния мы можем разделить целое на несколько одинаковых маленьких равносторонних треугольников.
Проведите вспомогательную линию в вертикальном направлении, соединив верхнюю и нижнюю точки посередине. Нетрудно найти, что «максимальная длина в вертикальном направлении» больше, чем «максимальная длина в горизонтальном направлении».
Предполагая, что длина стороны маленького равностороннего треугольника равна 1, а центр внутреннего шестиугольника является началом координат, координаты каждой точки можно рассчитать следующим образом:
Чтобы нарисовать изображение с использованием процентного позиционирования клипа, следующим шагом будет преобразование координат длины в процентные координаты.
Пусть максимальная длина в вертикальном направлении равна 100%, центр внутреннего шестиугольника по-прежнему является началом координат, а значения координат каждой точки преобразуются следующим образом:
Поскольку clip-path рисует начало координат в верхнем левом углу, правая сторона оси x положительна, а нижняя часть оси y положительна. Нужно сделать преобразование системы координат. который:
Новое значение координаты по оси X = старое значение координаты по оси X + 50%
Новое значение координаты оси Y = (старое значение координаты оси Y - 50%) * -1
Используйте метод многоугольника clip-path, чтобы нарисовать внутренний шестиугольник, и координаты были рассчитаны с помощью вышеуказанных шагов.
Код стиля выглядит следующим образом:
.sunny:after {
content: "";
position: absolute;
top: 50%;
left: 50%;
margin: -45px 0 0 -45px;
width: 90px;
height: 90px;
background: #FFEB3B;
clip-path: polygon(
50% 0%,
64.43% 25%,
93.3% 25%,
78.87% 50%,
93.3% 75%,
64.43% 75%,
50% 100%,
35.57% 75%,
6.7% 75%,
21.13% 50%,
6.7% 25%,
35.57% 25%);
z-index: 1;
animation: sunScale 2s linear infinite;
}
@keyframes sunScale {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
※Примечание: Safari необходимо изменить путь клипа на -webkit-clip-path. Поскольку код занимает слишком много места, здесь он не будет повторяться дважды.
Принцип реализации заключается в том, чтобы нарисовать маску внутреннего шестиугольника через clip-path и превратить желтый фон в конечный внутренний шестиугольник через маску.
Анимация реализует эффект переменного движения «увеличение и уменьшение» с помощью анимации ключевого кадра.
окончательный эффект:
4 облачно
Глядя на график, видно, что есть два облака: белое облако спереди и темное облако сзади. Кажется, что это нужно реализовать с :before и :after соответственно. Если бы это было сделано, элементы дождя и снега в последующих главах не имели бы лишних псевдоэлементов. Таким образом, с одним псевдоэлементом можно реализовать только два облака. Здесь используется «теневой клон» box-shadow!
Так как дождливые и снежные дни в следующих главах повторно используют стиль облаков, они написаны вместе Код выглядит следующим образом:
.cloudy:before,
.rainy:before,
.snowy:before {
content: "";
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%, -50%);
width: 36px;
height: 36px;
background: #fff;
border-radius: 50%;
z-index: 2;
}
Реальный элемент (реальное тело) — это круг. Используйте box-shadow, чтобы использовать проекцию в качестве «клона».
Давайте сначала посмотрим на свойства box-shadow:
box-shadow: h-shadow v-shadow blur spread color inset;
Детали параметра:
h-shadow: Горизонтальное смещение тени.
v-shadow: Вертикальное смещение тени.
размытие: расстояние размытия (то есть расстояние градиента, если установлено значение 0, градиента не будет).
распространение: размер проекции, через которую контролируется размер «теневого клона».
цвет: Цвет проекции, через который реализуются темные облака позади.
вставка: изменить на внутреннюю тень. Здесь не используется.
Попробуйте сначала скопировать теневой клон:
box-shadow: #fff 22px -15px 0 6px;
Продолжайте копировать несколько теневых клонов, полный код со всеми теневыми клонами выглядит следующим образом:
.cloudy:before,
.rainy:before,
.snowy:before {
content: "";
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%, -50%);
width: 36px;
height: 36px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 22px -15px 0 6px,
#fff 57px -6px 0 2px,
#fff 87px 4px 0 -4px,
#fff 33px 6px 0 6px,
#fff 61px 6px 0 2px,
#ccc 29px -23px 0 6px,
#ccc 64px -14px 0 2px,
#ccc 94px -4px 0 -4px;
z-index: 2;
}
Белые кружки (#fff) пяти клонов и серые кружки (#ccc) трех клонов составляют два облака.
Затем добавьте к облакам анимацию «плавания вверх и вниз»:
.cloudy:before {
animation: cloudMove 2s linear infinite;
}
@keyframes cloudMove {
0% {
transform: translate(-50%, -50%);
}
50% {
transform: translate(-50%, -60%);
}
100% {
transform: translate(-50%, -50%);
}
}
5 дождливых дней
Код Cloud повторно использует пасмурный день из главы 4. Капли дождя реализованы здесь с помощью псевдоэлемента :after.
Сначала реализуем каплю дождя (для удобства просмотра временно скрываем облака):
.rainy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 4px;
height: 14px;
background: #fff;
border-radius: 2px;
}
Затем "теневой клон" через box-shadow:
.rainy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 4px;
height: 14px;
background: #fff;
border-radius: 2px;
+ box-shadow:
+ #fff 25px -10px 0,
+ #fff 50px 0 0,
+ #fff 75px -10px 0,
+ #fff 0 25px 0,
+ #fff 25px 15px 0,
+ #fff 50px 25px 0,
+ #fff 75px 15px 0,
+ #fff 0 50px 0,
+ #fff 25px 40px 0,
+ #fff 50px 50px 0,
+ #fff 75px 40px 0;
}
Затем добавьте анимацию движения дождя и измените ее следующим образом:
.rainy:after {
...(略)
+ animation: rainDrop 2s linear infinite;
}
+ @keyframes rainDrop {
+ 0% {
+ transform: translate(0, 0) rotate(10deg);
+ }
+ 100% {
+ transform: translate(-4px, 24px) rotate(10deg);
+ box-shadow:
+ #fff 25px -10px 0,
+ #fff 50px 0 0,
+ #fff 75px -10px 0,
+ #fff 0 25px 0,
+ #fff 25px 15px 0,
+ #fff 50px 25px 0,
+ #fff 75px 15px 0,
+ rgba(255, 255, 255, 0) 0 50px 0,
+ rgba(255, 255, 255, 0) 25px 40px 0,
+ rgba(255, 255, 255, 0) 50px 50px 0,
+ rgba(255, 255, 255, 0) 75px 40px 0;
+ }
+ }
Анимация добавляет вращение на 10 градусов, наклон капли дождя и вертикальное движение.
Ключевым моментом здесь является то, что хотя суть и заключается в вертикальном движении, чтобы выглядеть как эффект «петли», нижняя капля дождя должна быть прозрачно-градиентной, а значения осей X и Y настраиваются одновременно, так, чтобы конечное положение совпадало с начальным положением, просто не отображалось "отключено".
Мы генерируем три ряда капель дождя, первый ряд заблокирован облаками, а два нижних ряда фактически видны. Когда первый ряд перемещается во второй ряд, исходный третий ряд становится прозрачным и невидимым, что точно так же, как и в исходном состоянии, реализуя бесшовное сшивание петель.
6 снежных дней
Разница между снежными и дождливыми днями заключается в том, что капли дождя заменяются кругами, а угол поворота отменяется. код показывает, как показано ниже:
.snowy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 8px;
height: 8px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
#fff 0 50px 0,
#fff 25px 40px 0,
#fff 50px 50px 0,
#fff 75px 40px 0;
animation: snowDrop 2s linear infinite;
}
@keyframes snowDrop {
0% {
transform: translateY(0);
}
100% {
transform: translateY(25px);
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
rgba(255, 255, 255, 0) 0 50px 0,
rgba(255, 255, 255, 0) 25px 40px 0,
rgba(255, 255, 255, 0) 50px 50px 0,
rgba(255, 255, 255, 0) 75px 40px 0;
}
}
7 Весь исходный код
Исходный код выглядит следующим образом, его легко вставить и сохранить как html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单标签!纯CSS实现动态晴阴雨雪</title>
</head>
<body>
<div class="weather sunny"></div>
<div class="weather cloudy"></div>
<div class="weather rainy"></div>
<div class="weather snowy"></div>
</body>
<style>
.weather {
position: relative;
display: inline-block;
width: 180px;
height: 240px;
background: #23b7e5;
border-radius: 8px;
}
.sunny:before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
background: #F6D963;
border-radius: 50%;
box-shadow: 0 0 20px #ff0;
z-index: 2;
}
.sunny:after {
content: "";
position: absolute;
top: 50%;
left: 50%;
margin: -45px 0 0 -45px;
width: 90px;
height: 90px;
background: #FFEB3B;
clip-path: polygon(
50% 0%,
64.43% 25%,
93.3% 25%,
78.87% 50%,
93.3% 75%,
64.43% 75%,
50% 100%,
35.57% 75%,
6.7% 75%,
21.13% 50%,
6.7% 25%,
35.57% 25%);
z-index: 1;
animation: sunScale 2s linear infinite;
}
@keyframes sunScale {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.cloudy:before,
.rainy:before,
.snowy:before {
content: "";
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%, -50%);
width: 36px;
height: 36px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 22px -15px 0 6px,
#fff 57px -6px 0 2px,
#fff 87px 4px 0 -4px,
#fff 33px 6px 0 6px,
#fff 61px 6px 0 2px,
#ccc 29px -23px 0 6px,
#ccc 64px -14px 0 2px,
#ccc 94px -4px 0 -4px;
z-index: 2;
}
.cloudy:before {
animation: cloudMove 2s linear infinite;
}
@keyframes cloudMove {
0% {
transform: translate(-50%, -50%);
}
50% {
transform: translate(-50%, -60%);
}
100% {
transform: translate(-50%, -50%);
}
}
.rainy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 4px;
height: 14px;
background: #fff;
border-radius: 2px;
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
#fff 0 50px 0,
#fff 25px 40px 0,
#fff 50px 50px 0,
#fff 75px 40px 0;
animation: rainDrop 2s linear infinite;
}
@keyframes rainDrop {
0% {
transform: translate(0, 0) rotate(10deg);
}
100% {
transform: translate(-4px, 24px) rotate(10deg);
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
rgba(255, 255, 255, 0) 0 50px 0,
rgba(255, 255, 255, 0) 25px 40px 0,
rgba(255, 255, 255, 0) 50px 50px 0,
rgba(255, 255, 255, 0) 75px 40px 0;
}
}
.snowy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 8px;
height: 8px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
#fff 0 50px 0,
#fff 25px 40px 0,
#fff 50px 50px 0,
#fff 75px 40px 0;
animation: snowDrop 2s linear infinite;
}
@keyframes snowDrop {
0% {
transform: translateY(0);
}
100% {
transform: translateY(25px);
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
rgba(255, 255, 255, 0) 0 50px 0,
rgba(255, 255, 255, 0) 25px 40px 0,
rgba(255, 255, 255, 0) 50px 50px 0,
rgba(255, 255, 255, 0) 75px 40px 0;
}
}
</style>
</html>
Вышеизложенное представляет собой обмен высококлассным геймплеем CSS в этом выпуске. Добро пожаловать, чтобы пересылать, обмениваться и делиться.
Еще интересные порталы:
[Технология комической речи] Серия уроков комиксов по CSS (1-5 лекций)
[Технология комической речи] Серия уроков комиксов по CSS (6-10 лекций)
[Технология комической речи] Серия уроков комиксов по CSS (11-15 лекций)
Добро пожаловать в мой личный общедоступный аккаунт WeChat, чтобы получать последние статьи в любое время ^_^