init: коллекция анимаций

— Добавлен Rolling Letters Loader (текстовый барабан)
— Добавлен Helix DNA Loader (3D спираль)
— Добавлен Lightsaber Fight Loader (сражение на мечах)
— Добавлен Pancake Cooking Loader (подбрасывание блинчика)
— Добавлен Pong Game Loader (ретро-игра)
— Создан общий README.md с навигационной таблицей
This commit is contained in:
2026-04-04 21:40:15 +03:00
commit 29324fca97
19 changed files with 2202 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
# ⌛ Animated Loaders Collection
Сборник эффектных индикаторов загрузки для современных веб-интерфейсов.
Все лоадеры реализованы на **Pure CSS**, что гарантирует высокую производительность и отсутствие лишних зависимостей.
## Обзор коллекции
| Превью | Компонент | Стиль | Особенности |
| :----- | :----------------------------------- | :----------- | :------------------------------------------ |
| 🎰 | [`Rolling Letters`](./rolling-text/) | Текстовый | Эффект барабана и каскадное выпадение букв. |
| 🧬 | [`Helix DNA`](./helix-dna/) | 3D / Научный | Сложная анимация вращения двойной спирали. |
| ⚔️ | [`Lightsaber Fight`](./lightsaber/) | Креатив | Мини-сюжет сражения на мечах с искрами. |
| 🥞 | [`Pancake Cooking`](./pancake/) | Сюжетный | Детальная анимация подбрасывания блинчика. |
| 🎾 | [`Pong Game`](./pong-game/) | Ретро | Минималистичный геймплей легендарной игры. |
## Технологии
- **HTML5** (Семантическая разметка)
- **CSS3 Animations** (`@keyframes`, `transitions`, `transforms`)
- **Zero JS** (Все анимации работают исключительно на стилях)
+15
View File
@@ -0,0 +1,15 @@
# 🧬 Helix CSS Loader
Сложный анимированный лоадер, имитирующий вращение двойной спирали (DNA Helix). Построен на чистом CSS с использованием 26 анимированных элементов.
### Особенности
- **3D Illusion**: Эффект объема достигается за счет синхронизации перемещения (`translate3d`), изменения масштаба (`scale`) и управления слоями (`z-index`).
- **Smooth Gradient**: Фон с использованием `linear-gradient` подчеркивает глубину анимации.
- **Pure CSS**: Не требует JavaScript, вся логика завязана на задержках (`animation-delay`) для каждого отдельного "узла" спирали.
### Технические детали
- **Movement**: Ключевой кадр `@keyframes movement` отвечает за вертикальное перемещение.
- **Size/Opacity**: `@keyframes size-opacity` создает эффект приближения и удаления точек, меняя их размер и прозрачность.
- **Dual Color**: Четные и нечетные элементы имеют разные цвета (белый и ярко-розовый) для визуального разделения двух нитей спирали.
+42
View File
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Helix CSS Loader</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<div class="loader">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
<!-- partial -->
</body>
</html>
+355
View File
@@ -0,0 +1,355 @@
html,
body {
height: 100%;
}
body {
align-items: center;
background: #d65b9e;
background: linear-gradient(45deg, #d65b9e 1%, #f699cb 22%, #ffacd9 51%, #f699cb 83%, #d65b9e 100%);
display: flex;
justify-content: center;
}
.loader {
position: relative;
}
.loader .dot {
-webkit-animation-name: movement;
animation-name: movement;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
height: 10px;
position: absolute;
top: -10px;
transform: translate3d(0, -25px, 0) scale(1);
width: 10px;
}
.loader .dot:nth-of-type(1) {
-webkit-animation-delay: -0.1s;
animation-delay: -0.1s;
left: 150px;
}
.loader .dot:nth-of-type(1)::before {
-webkit-animation-delay: -0.1s;
animation-delay: -0.1s;
}
.loader .dot:nth-of-type(2) {
-webkit-animation-delay: -1.2s;
animation-delay: -1.2s;
left: 150px;
}
.loader .dot:nth-of-type(2)::before {
-webkit-animation-delay: -1.2s;
animation-delay: -1.2s;
}
.loader .dot:nth-of-type(3) {
-webkit-animation-delay: -0.3s;
animation-delay: -0.3s;
left: 125px;
}
.loader .dot:nth-of-type(3)::before {
-webkit-animation-delay: -0.3s;
animation-delay: -0.3s;
}
.loader .dot:nth-of-type(4) {
-webkit-animation-delay: -1.4s;
animation-delay: -1.4s;
left: 125px;
}
.loader .dot:nth-of-type(4)::before {
-webkit-animation-delay: -1.4s;
animation-delay: -1.4s;
}
.loader .dot:nth-of-type(5) {
-webkit-animation-delay: -0.5s;
animation-delay: -0.5s;
left: 100px;
}
.loader .dot:nth-of-type(5)::before {
-webkit-animation-delay: -0.5s;
animation-delay: -0.5s;
}
.loader .dot:nth-of-type(6) {
-webkit-animation-delay: -1.6s;
animation-delay: -1.6s;
left: 100px;
}
.loader .dot:nth-of-type(6)::before {
-webkit-animation-delay: -1.6s;
animation-delay: -1.6s;
}
.loader .dot:nth-of-type(7) {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s;
left: 75px;
}
.loader .dot:nth-of-type(7)::before {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s;
}
.loader .dot:nth-of-type(8) {
-webkit-animation-delay: -1.8s;
animation-delay: -1.8s;
left: 75px;
}
.loader .dot:nth-of-type(8)::before {
-webkit-animation-delay: -1.8s;
animation-delay: -1.8s;
}
.loader .dot:nth-of-type(9) {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
left: 50px;
}
.loader .dot:nth-of-type(9)::before {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.loader .dot:nth-of-type(10) {
-webkit-animation-delay: -2s;
animation-delay: -2s;
left: 50px;
}
.loader .dot:nth-of-type(10)::before {
-webkit-animation-delay: -2s;
animation-delay: -2s;
}
.loader .dot:nth-of-type(11) {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
left: 25px;
}
.loader .dot:nth-of-type(11)::before {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.loader .dot:nth-of-type(12) {
-webkit-animation-delay: -2.2s;
animation-delay: -2.2s;
left: 25px;
}
.loader .dot:nth-of-type(12)::before {
-webkit-animation-delay: -2.2s;
animation-delay: -2.2s;
}
.loader .dot:nth-of-type(13) {
-webkit-animation-delay: -1.3s;
animation-delay: -1.3s;
left: 0px;
}
.loader .dot:nth-of-type(13)::before {
-webkit-animation-delay: -1.3s;
animation-delay: -1.3s;
}
.loader .dot:nth-of-type(14) {
-webkit-animation-delay: -2.4s;
animation-delay: -2.4s;
left: 0px;
}
.loader .dot:nth-of-type(14)::before {
-webkit-animation-delay: -2.4s;
animation-delay: -2.4s;
}
.loader .dot:nth-of-type(15) {
-webkit-animation-delay: -1.5s;
animation-delay: -1.5s;
left: -25px;
}
.loader .dot:nth-of-type(15)::before {
-webkit-animation-delay: -1.5s;
animation-delay: -1.5s;
}
.loader .dot:nth-of-type(16) {
-webkit-animation-delay: -2.6s;
animation-delay: -2.6s;
left: -25px;
}
.loader .dot:nth-of-type(16)::before {
-webkit-animation-delay: -2.6s;
animation-delay: -2.6s;
}
.loader .dot:nth-of-type(17) {
-webkit-animation-delay: -1.7s;
animation-delay: -1.7s;
left: -50px;
}
.loader .dot:nth-of-type(17)::before {
-webkit-animation-delay: -1.7s;
animation-delay: -1.7s;
}
.loader .dot:nth-of-type(18) {
-webkit-animation-delay: -2.8s;
animation-delay: -2.8s;
left: -50px;
}
.loader .dot:nth-of-type(18)::before {
-webkit-animation-delay: -2.8s;
animation-delay: -2.8s;
}
.loader .dot:nth-of-type(19) {
-webkit-animation-delay: -1.9s;
animation-delay: -1.9s;
left: -75px;
}
.loader .dot:nth-of-type(19)::before {
-webkit-animation-delay: -1.9s;
animation-delay: -1.9s;
}
.loader .dot:nth-of-type(20) {
-webkit-animation-delay: -3s;
animation-delay: -3s;
left: -75px;
}
.loader .dot:nth-of-type(20)::before {
-webkit-animation-delay: -3s;
animation-delay: -3s;
}
.loader .dot:nth-of-type(21) {
-webkit-animation-delay: -2.1s;
animation-delay: -2.1s;
left: -100px;
}
.loader .dot:nth-of-type(21)::before {
-webkit-animation-delay: -2.1s;
animation-delay: -2.1s;
}
.loader .dot:nth-of-type(22) {
-webkit-animation-delay: -3.2s;
animation-delay: -3.2s;
left: -100px;
}
.loader .dot:nth-of-type(22)::before {
-webkit-animation-delay: -3.2s;
animation-delay: -3.2s;
}
.loader .dot:nth-of-type(23) {
-webkit-animation-delay: -2.3s;
animation-delay: -2.3s;
left: -125px;
}
.loader .dot:nth-of-type(23)::before {
-webkit-animation-delay: -2.3s;
animation-delay: -2.3s;
}
.loader .dot:nth-of-type(24) {
-webkit-animation-delay: -3.4s;
animation-delay: -3.4s;
left: -125px;
}
.loader .dot:nth-of-type(24)::before {
-webkit-animation-delay: -3.4s;
animation-delay: -3.4s;
}
.loader .dot:nth-of-type(25) {
-webkit-animation-delay: -2.5s;
animation-delay: -2.5s;
left: -150px;
}
.loader .dot:nth-of-type(25)::before {
-webkit-animation-delay: -2.5s;
animation-delay: -2.5s;
}
.loader .dot:nth-of-type(26) {
-webkit-animation-delay: -3.6s;
animation-delay: -3.6s;
left: -150px;
}
.loader .dot:nth-of-type(26)::before {
-webkit-animation-delay: -3.6s;
animation-delay: -3.6s;
}
.loader .dot::before {
-webkit-animation-name: size-opacity;
animation-name: size-opacity;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: ease;
animation-timing-function: ease;
background: white;
border-radius: 50%;
content: "";
display: block;
height: 100%;
width: 100%;
}
.loader .dot:nth-of-type(even)::before {
background-color: #ff47aa;
box-shadow: inset 0 0 4px #ff1492;
}
@-webkit-keyframes movement {
0% {
transform: translate3d(0, -25px, 0);
z-index: 0;
}
50% {
transform: translate3d(0, 25px, 0);
z-index: 10;
}
100% {
transform: translate3d(0, -25px, 0);
z-index: -5;
}
}
@keyframes movement {
0% {
transform: translate3d(0, -25px, 0);
z-index: 0;
}
50% {
transform: translate3d(0, 25px, 0);
z-index: 10;
}
100% {
transform: translate3d(0, -25px, 0);
z-index: -5;
}
}
@-webkit-keyframes size-opacity {
0% {
opacity: 1;
transform: scale(1);
}
25% {
transform: scale(1.5);
}
50% {
opacity: 1;
}
75% {
opacity: 0.35;
transform: scale(0.5);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframes size-opacity {
0% {
opacity: 1;
transform: scale(1);
}
25% {
transform: scale(1.5);
}
50% {
opacity: 1;
}
75% {
opacity: 0.35;
transform: scale(0.5);
}
100% {
opacity: 1;
transform: scale(1);
}
}
+109
View File
@@ -0,0 +1,109 @@
html,
body {
height: 100%;
}
body {
align-items: center;
background: #d65b9e;
background: linear-gradient(45deg, #d65b9e 1%,#f699cb 22%,#ffacd9 51%,#f699cb 83%,#d65b9e 100%);
display: flex;
justify-content: center;
}
$dot-count: 26;
$dot-size: 10px;
$dot-space: 15px;
$dot-start: (($dot-count / 2 + 1) * ($dot-size + $dot-space)) / 2;
$animation-time: 2s;
$animation-distance: 25px;
.loader {
position: relative;
.dot {
animation-name: movement;
animation-duration: $animation-time;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
height: $dot-size;
position: absolute;
top: -#{$dot-size};
transform: translate3d(0, -#{$animation-distance}, 0) scale(1);
width: $dot-size;
@for $i from 1 through $dot-count {
$dot-move: ceil($i / 2);
$dot-pos: $dot-start - (($dot-size + $dot-space) * $dot-move);
$animation-delay: -#{$i * .1}s;
@if $i % 2 == 0 {
$animation-delay: -#{($i * .1) + ($animation-time / 2)};
}
&:nth-of-type(#{$i}) {
animation-delay: $animation-delay;
left: $dot-pos;
&::before {
animation-delay: $animation-delay;
}
}
}
&::before {
animation-name: size-opacity;
animation-duration: $animation-time;
animation-iteration-count: infinite;
animation-timing-function: ease;
background: white;
border-radius: 50%;
content: '';
display: block;
height: 100%;
width: 100%;
}
&:nth-of-type(even)::before {
background-color: #ff47aa;
box-shadow: inset 0 0 4px darken(#ff47aa, 10%);
}
}
}
@keyframes movement {
0% {
transform: translate3d(0, -#{$animation-distance}, 0);
z-index: 0;
}
50% {
transform: translate3d(0, #{$animation-distance}, 0);
z-index: 10;
}
100% {
transform: translate3d(0, -#{$animation-distance}, 0);
z-index: -5;
}
}
@keyframes size-opacity {
0% {
opacity: 1;
transform: scale(1);
}
25% {
transform: scale(1.5);
}
50% {
opacity: 1;
}
75% {
opacity: .35;
transform: scale(.5);
}
100% {
opacity: 1;
transform: scale(1);
}
}
+15
View File
@@ -0,0 +1,15 @@
# ⚔️ Lightsaber Fight Loader
Уникальный тематический индикатор загрузки, выполненный в стиле сражения на световых мечах. 100% Pure CSS.
### Особенности
- **Интерактивный сюжет**: Анимация включает в себя активацию мечей, само «сражение» (столкновение) и появление искр.
- **Particle System**: Эффект искр при столкновении реализован через `@keyframes` и изменение прозрачности отдельных элементов.
- **Star Wars Vibe**: Используются классические цвета (зеленый и красный) с соответствующим свечением (`box-shadow`).
### Технические детали
- **Lightsabers**: Рукоятки — это основные блоки, а сами лучи созданы с помощью псевдоэлементов `:before`.
- **Fight Logic**: Анимации `fightleft` и `fightright` синхронизированы так, чтобы мечи пересекались в одной точке в определенный момент времени.
- **Glow Effect**: Динамическое изменение `box-shadow` создает эффект пульсирующего света.
+28
View File
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Lightsaber Fight Loader</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<body>
<h1>Lightsaber Fight Loader</h1>
<p>A little 100% CSS loader inspired in a Lightsaber fight :)</p>
<div id="loader">
<div class="ls-particles ls-part-1"></div>
<div class="ls-particles ls-part-2"></div>
<div class="ls-particles ls-part-3"></div>
<div class="ls-particles ls-part-4"></div>
<div class="ls-particles ls-part-5"></div>
<div class="lightsaber ls-left ls-green"></div>
<div class="lightsaber ls-right ls-red"></div>
</div>
</body>
<!-- partial -->
</body>
</html>
+765
View File
@@ -0,0 +1,765 @@
body {
position: relative;
background-color: #eee;
min-height: 380px;
}
h1 {
text-align: center;
font-family: Helvetica, Arial, sans-serif;
font-weight: 200;
color: #333;
font-size: 26px;
margin: 40px 0 15px;
}
p {
text-align: center;
font-family: Helvetica, Arial, sans-serif;
font-weight: 200;
color: #666;
font-size: 16px;
margin: 10px 0;
font-style: italic;
}
p.small {
text-align: center;
color: #999;
font-size: 14px;
margin: 0 0 40px;
font-style: normal;
}
p a {
text-decoration: none;
font-weight: bold;
color: #666;
}
p a:hover {
color: #608A00;
}
#loader {
width: 80px;
height: 40px;
position: absolute;
top: 50%;
left: 50%;
margin: -20px -40px;
z-index: 1000;
}
.lightsaber {
position: absolute;
width: 4px;
height: 12px;
background-color: #666;
border-radius: 1px;
bottom: 0;
}
.lightsaber.ls-left {
left: 0;
}
.lightsaber.ls-right {
right: 0;
}
.lightsaber:before {
position: absolute;
content: ' ';
display: block;
width: 2px;
height: 25px;
max-height: 1px;
left: 1px;
top: 1px;
background-color: #fff;
border-radius: 1px;
-webkit-transform: rotateZ(180deg);
transform: rotateZ(180deg);
-webkit-transform-origin: center top;
-ms-transform-origin: center top;
transform-origin: center top;
}
.lightsaber:after {
position: absolute;
content: ' ';
display: block;
width: 2px;
height: 2px;
left: 1px;
top: 4px;
background-color: #fff;
border-radius: 50%;
}
.ls-particles {
position: absolute;
left: 42px;
top: 10px;
width: 1px;
height: 5px;
background-color: rgb(51, 51, 51, 0);
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
}
.lightsaber.ls-green:before {
-webkit-animation: showlightgreen 2s ease-in-out infinite 1s; animation: showlightgreen 2s ease-in-out infinite 1s;
}
.lightsaber.ls-red:before {
-webkit-animation: showlightred 2s ease-in-out infinite 1s; animation: showlightred 2s ease-in-out infinite 1s;
}
.lightsaber.ls-left {
-webkit-animation: fightleft 2s ease-in-out infinite 1s; animation: fightleft 2s ease-in-out infinite 1s;
}
.lightsaber.ls-right {
-webkit-animation: fightright 2s ease-in-out infinite 1s; animation: fightright 2s ease-in-out infinite 1s;
}
.ls-particles.ls-part-1 {
-webkit-animation: particles1 2s ease-out infinite 1s; animation: particles1 2s ease-out infinite 1s;
}
.ls-particles.ls-part-2 {
-webkit-animation: particles2 2s ease-out infinite 1s; animation: particles2 2s ease-out infinite 1s;
}
.ls-particles.ls-part-3 {
-webkit-animation: particles3 2s ease-out infinite 1s; animation: particles3 2s ease-out infinite 1s;
}
.ls-particles.ls-part-4 {
-webkit-animation: particles4 2s ease-out infinite 1s; animation: particles4 2s ease-out infinite 1s;
}
.ls-particles.ls-part-5 {
-webkit-animation: particles5 2s ease-out infinite 1s; animation: particles5 2s ease-out infinite 1s;
}
@-webkit-keyframes showlightgreen {
0% {
max-height: 0;
box-shadow: 0 0 0 0 #87c054;
}
5% {
box-shadow: 0 0 4px 2px #87c054;
}
10% {
max-height: 22px;
}
80% {
max-height: 22px;
}
85% {
box-shadow: 0 0 4px 2px #87c054;
}
100% {
max-height: 0;
box-shadow: 0 0 0 0 #87c054;
}
}
@-webkit-keyframes showlightred {
0% {
max-height: 0;
box-shadow: 0 0 0 0 #f06363;
}
20% {
box-shadow: 0 0 4px 2px #f06363;
}
25% {
max-height: 22px;
}
80% {
max-height: 22px;
}
85% {
box-shadow: 0 0 4px 2px #f06363;
}
100% {
max-height: 0;
box-shadow: 0 0 0 0 #f06363;
}
}
@-webkit-keyframes fightleft {
0% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
left: 0;
bottom: 0;
}
30% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
bottom: 0;
}
40% {
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg);
left: 0;
bottom: 2px;
}
45%{
-webkit-transform: rotateZ(65deg);
transform: rotateZ(65deg);
left: 0;
}
65%{
-webkit-transform: rotateZ(410deg);
transform: rotateZ(410deg);
left: 30px;
bottom: 10px;
}
95% {
-webkit-transform: rotateZ(410deg);
transform: rotateZ(410deg);
left: 0;
bottom: 0;
}
100% {
-webkit-transform: rotateZ(360deg);
transform: rotateZ(360deg);
left: 0;
bottom: 0;
}
}
@-webkit-keyframes fightright {
0% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
right: 0;
bottom: 0;
}
30% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
bottom: 0;
}
45% {
-webkit-transform: rotateZ(-45deg);
transform: rotateZ(-45deg);
right: 0;
bottom: 2px;
}
50%{
-webkit-transform: rotateZ(-65deg);
transform: rotateZ(-65deg);
right: 0;
}
68%{
-webkit-transform: rotateZ(-410deg);
transform: rotateZ(-410deg);
right: 27px;
bottom: 13px;
}
95% {
-webkit-transform: rotateZ(-410deg);
transform: rotateZ(-410deg);
right: 0;
bottom: 0;
}
100% {
-webkit-transform: rotateZ(-360deg);
transform: rotateZ(-360deg);
right: 0;
bottom: 0;
}
}
@-webkit-keyframes particles1 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(35deg) translateY(0px);
transform: rotateZ(35deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(35deg) translateY(0px);
transform: rotateZ(35deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(35deg) translateY(0px);
transform: rotateZ(35deg) translateY(0px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(35deg) translateY(-30px);
transform: rotateZ(35deg) translateY(-30px);
}
}
@-webkit-keyframes particles2 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(0px);
transform: rotateZ(-65deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(0px);
transform: rotateZ(-65deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(-65deg) translateY(0px);
transform: rotateZ(-65deg) translateY(0px);
}
95% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(-40px);
transform: rotateZ(-65deg) translateY(-40px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(-40px);
transform: rotateZ(-65deg) translateY(-40px);
}
}
@-webkit-keyframes particles3 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(0px);
transform: rotateZ(-75deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(0px);
transform: rotateZ(-75deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(-75deg) translateY(0px);
transform: rotateZ(-75deg) translateY(0px);
}
97% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(-35px);
transform: rotateZ(-75deg) translateY(-35px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(-35px);
transform: rotateZ(-75deg) translateY(-35px);
}
}
@-webkit-keyframes particles4 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(0px);
transform: rotateZ(-25deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(0px);
transform: rotateZ(-25deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(-25deg) translateY(0px);
transform: rotateZ(-25deg) translateY(0px);
}
97% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(-30px);
transform: rotateZ(-25deg) translateY(-30px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(-30px);
transform: rotateZ(-25deg) translateY(-30px);
}
}
@-webkit-keyframes particles5 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(0px);
transform: rotateZ(65deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(0px);
transform: rotateZ(65deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(65deg) translateY(0px);
transform: rotateZ(65deg) translateY(0px);
}
97% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(-35px);
transform: rotateZ(65deg) translateY(-35px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(-35px);
transform: rotateZ(65deg) translateY(-35px);
}
}
@keyframes showlightgreen {
0% {
max-height: 0;
box-shadow: 0 0 0 0 #87c054;
}
5% {
box-shadow: 0 0 4px 2px #87c054;
}
10% {
max-height: 22px;
}
80% {
max-height: 22px;
}
85% {
box-shadow: 0 0 4px 2px #87c054;
}
100% {
max-height: 0;
box-shadow: 0 0 0 0 #87c054;
}
}
@keyframes showlightred {
0% {
max-height: 0;
box-shadow: 0 0 0 0 #f06363;
}
20% {
box-shadow: 0 0 4px 2px #f06363;
}
25% {
max-height: 22px;
}
80% {
max-height: 22px;
}
85% {
box-shadow: 0 0 4px 2px #f06363;
}
100% {
max-height: 0;
box-shadow: 0 0 0 0 #f06363;
}
}
@keyframes fightleft {
0% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
left: 0;
bottom: 0;
}
30% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
bottom: 0;
}
40% {
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg);
left: 0;
bottom: 2px;
}
45%{
-webkit-transform: rotateZ(65deg);
transform: rotateZ(65deg);
left: 0;
}
65%{
-webkit-transform: rotateZ(410deg);
transform: rotateZ(410deg);
left: 30px;
bottom: 10px;
}
95% {
-webkit-transform: rotateZ(410deg);
transform: rotateZ(410deg);
left: 0;
bottom: 0;
}
100% {
-webkit-transform: rotateZ(360deg);
transform: rotateZ(360deg);
left: 0;
bottom: 0;
}
}
@keyframes fightright {
0% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
right: 0;
bottom: 0;
}
30% {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
bottom: 0;
}
45% {
-webkit-transform: rotateZ(-45deg);
transform: rotateZ(-45deg);
right: 0;
bottom: 2px;
}
50%{
-webkit-transform: rotateZ(-65deg);
transform: rotateZ(-65deg);
right: 0;
}
68%{
-webkit-transform: rotateZ(-410deg);
transform: rotateZ(-410deg);
right: 27px;
bottom: 13px;
}
95% {
-webkit-transform: rotateZ(-410deg);
transform: rotateZ(-410deg);
right: 0;
bottom: 0;
}
100% {
-webkit-transform: rotateZ(-360deg);
transform: rotateZ(-360deg);
right: 0;
bottom: 0;
}
}
@keyframes particles1 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(35deg) translateY(0px);
transform: rotateZ(35deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(35deg) translateY(0px);
transform: rotateZ(35deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(35deg) translateY(0px);
transform: rotateZ(35deg) translateY(0px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(35deg) translateY(-30px);
transform: rotateZ(35deg) translateY(-30px);
}
}
@keyframes particles2 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(0px);
transform: rotateZ(-65deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(0px);
transform: rotateZ(-65deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(-65deg) translateY(0px);
transform: rotateZ(-65deg) translateY(0px);
}
95% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(-40px);
transform: rotateZ(-65deg) translateY(-40px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-65deg) translateY(-40px);
transform: rotateZ(-65deg) translateY(-40px);
}
}
@keyframes particles3 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(0px);
transform: rotateZ(-75deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(0px);
transform: rotateZ(-75deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(-75deg) translateY(0px);
transform: rotateZ(-75deg) translateY(0px);
}
97% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(-35px);
transform: rotateZ(-75deg) translateY(-35px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-75deg) translateY(-35px);
transform: rotateZ(-75deg) translateY(-35px);
}
}
@keyframes particles4 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(0px);
transform: rotateZ(-25deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(0px);
transform: rotateZ(-25deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(-25deg) translateY(0px);
transform: rotateZ(-25deg) translateY(0px);
}
97% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(-30px);
transform: rotateZ(-25deg) translateY(-30px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(-25deg) translateY(-30px);
transform: rotateZ(-25deg) translateY(-30px);
}
}
@keyframes particles5 {
0% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(0px);
transform: rotateZ(65deg) translateY(0px);
}
63% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(0px);
transform: rotateZ(65deg) translateY(0px);
}
64% {
background-color: rgba(51, 51, 51,1);
-webkit-transform: rotateZ(65deg) translateY(0px);
transform: rotateZ(65deg) translateY(0px);
}
97% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(-35px);
transform: rotateZ(65deg) translateY(-35px);
}
100% {
background-color: rgba(51, 51, 51,0);
-webkit-transform: rotateZ(65deg) translateY(-35px);
transform: rotateZ(65deg) translateY(-35px);
}
}
+15
View File
@@ -0,0 +1,15 @@
# 🥞 Making Pancake Loader
Невероятно детальный и "вкусный" индикатор загрузки, имитирующий приготовление блинчика на сковороде. Полностью реализован на чистом CSS.
### Особенности
- **Комплексная физика**: Анимация включает в себя наклон сковороды (`flip`), подбрасывание блинчика (`jump`) и его переворот в воздухе (`fly`).
- **Эффект пара**: Реализован через систему "пузырьков" (`.bubble`) с разными задержками и кривыми Безье для естественности.
- **Адаптивность (vh/vw)**: Размеры элементов привязаны к высоте экрана, что позволяет лоадеру корректно масштабироваться.
### Технические детали
- **Keyframes Magic**: Используется 5 различных сценариев анимации, работающих синхронно.
- **3D Transform**: Переворот блинчика имитируется через `rotateX` и `rotateY`.
- **Typography**: Интегрирован шрифт "Amatic SC" через Google Fonts для создания уютной атмосферы.
+31
View File
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - &#39;Making pancake&#39; loader</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<h1>Cooking in progress..</h1>
<div id="cooking">
<div class="bubble"></div>
<div class="bubble"></div>
<div class="bubble"></div>
<div class="bubble"></div>
<div class="bubble"></div>
<div id="area">
<div id="sides">
<div id="pan"></div>
<div id="handle"></div>
</div>
<div id="pancake">
<div id="pastry"></div>
</div>
</div>
</div>
<!-- partial -->
</body>
</html>
+236
View File
@@ -0,0 +1,236 @@
@import url("https://fonts.googleapis.com/css?family=Amatic+SC");
body {
background-color: #ffde6b;
height: 100vh;
width: 100vw;
overflow: hidden;
}
h1 {
position: relative;
margin: 0 auto;
top: 25vh;
width: 100vw;
text-align: center;
font-family: "Amatic SC";
font-size: 6vh;
color: #333;
opacity: 0.75;
animation: pulse 2.5s linear infinite;
}
#cooking {
position: relative;
margin: 0 auto;
top: 0;
width: 75vh;
height: 75vh;
overflow: hidden;
}
#cooking .bubble {
position: absolute;
border-radius: 100%;
box-shadow: 0 0 0.25vh #4d4d4d;
opacity: 0;
}
#cooking .bubble:nth-child(1) {
margin-top: 2.5vh;
left: 58%;
width: 2.5vh;
height: 2.5vh;
background-color: #454545;
animation: bubble 2s cubic-bezier(0.53, 0.16, 0.39, 0.96) infinite;
}
#cooking .bubble:nth-child(2) {
margin-top: 3vh;
left: 52%;
width: 2vh;
height: 2vh;
background-color: #3d3d3d;
animation: bubble 2s ease-in-out 0.35s infinite;
}
#cooking .bubble:nth-child(3) {
margin-top: 1.8vh;
left: 50%;
width: 1.5vh;
height: 1.5vh;
background-color: #333;
animation: bubble 1.5s cubic-bezier(0.53, 0.16, 0.39, 0.96) 0.55s infinite;
}
#cooking .bubble:nth-child(4) {
margin-top: 2.7vh;
left: 56%;
width: 1.2vh;
height: 1.2vh;
background-color: #2b2b2b;
animation: bubble 1.8s cubic-bezier(0.53, 0.16, 0.39, 0.96) 0.9s infinite;
}
#cooking .bubble:nth-child(5) {
margin-top: 2.7vh;
left: 63%;
width: 1.1vh;
height: 1.1vh;
background-color: #242424;
animation: bubble 1.6s ease-in-out 1s infinite;
}
#cooking #area {
position: absolute;
bottom: 0;
right: 0;
width: 50%;
height: 50%;
background-color: transparent;
transform-origin: 15% 60%;
animation: flip 2.1s ease-in-out infinite;
}
#cooking #area #sides {
position: absolute;
width: 100%;
height: 100%;
transform-origin: 15% 60%;
animation: switchSide 2.1s ease-in-out infinite;
}
#cooking #area #sides #handle {
position: absolute;
bottom: 18%;
right: 80%;
width: 35%;
height: 20%;
background-color: transparent;
border-top: 1vh solid #333;
border-left: 1vh solid transparent;
border-radius: 100%;
transform: rotate(20deg) rotateX(0deg) scale(1.3, 0.9);
}
#cooking #area #sides #pan {
position: absolute;
bottom: 20%;
right: 30%;
width: 50%;
height: 8%;
background-color: #333;
border-radius: 0 0 1.4em 1.4em;
transform-origin: -15% 0;
}
#cooking #area #pancake {
position: absolute;
top: 24%;
width: 100%;
height: 100%;
transform: rotateX(85deg);
animation: jump 2.1s ease-in-out infinite;
}
#cooking #area #pancake #pastry {
position: absolute;
bottom: 26%;
right: 37%;
width: 40%;
height: 45%;
background-color: #333;
box-shadow: 0 0 3px 0 #333;
border-radius: 100%;
transform-origin: -20% 0;
animation: fly 2.1s ease-in-out infinite;
}
@keyframes jump {
0% {
top: 24%;
transform: rotateX(85deg);
}
25% {
top: 10%;
transform: rotateX(0deg);
}
50% {
top: 30%;
transform: rotateX(85deg);
}
75% {
transform: rotateX(0deg);
}
100% {
transform: rotateX(85deg);
}
}
@keyframes flip {
0% {
transform: rotate(0deg);
}
5% {
transform: rotate(-27deg);
}
30%, 50% {
transform: rotate(0deg);
}
55% {
transform: rotate(27deg);
}
83.3% {
transform: rotate(0deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes switchSide {
0% {
transform: rotateY(0deg);
}
50% {
transform: rotateY(180deg);
}
100% {
transform: rotateY(0deg);
}
}
@keyframes fly {
0% {
bottom: 26%;
transform: rotate(0deg);
}
10% {
bottom: 40%;
}
50% {
bottom: 26%;
transform: rotate(-190deg);
}
80% {
bottom: 40%;
}
100% {
bottom: 26%;
transform: rotate(0deg);
}
}
@keyframes bubble {
0% {
transform: scale(0.15, 0.15);
top: 80%;
opacity: 0;
}
50% {
transform: scale(1.1, 1.1);
opacity: 1;
}
100% {
transform: scale(0.33, 0.33);
top: 60%;
opacity: 0;
}
}
@keyframes pulse {
0% {
transform: scale(1, 1);
opacity: 0.25;
}
50% {
transform: scale(1.2, 1);
opacity: 1;
}
100% {
transform: scale(1, 1);
opacity: 0.25;
}
}
+250
View File
@@ -0,0 +1,250 @@
@import url('https://fonts.googleapis.com/css?family=Amatic+SC');
$anim_time: 2.1; // main pan/pancake animation (in seconds)
$flatten_deg: 85; // how round will the pancake be at the top/peak (in deg), affecting general animation though so not really adjustable
$angle: 27; // max pan's angle while flipping (in deg)
$peak: 40%; // pancake's highest level, obviously ;)
$color_back: #ffde6b; // background
$color: #333; // the rest
body {
background-color: $color_back;
height: 100vh;
width: 100vw;
overflow: hidden;
}
h1 {
position: relative;
margin: 0 auto;
top: 25vh;
width: 100vw;
text-align: center;
font-family: 'Amatic SC';
font-size: 6vh;
color: $color;
opacity: .75;
animation: pulse 2.5s linear infinite;
}
#cooking {
position: relative;
margin: 0 auto;
top: 0;
width: 75vh;
height: 75vh;
overflow: hidden;
.bubble {
position: absolute;
border-radius: 100%;
box-shadow: 0 0 .25vh lighten($color, 10%);
opacity: 0;
}
.bubble:nth-child(1) {
margin-top: 2.5vh;
left: 58%;
width: 2.5vh;
height: 2.5vh;
background-color: lighten($color, 7%);
animation: bubble 2s cubic-bezier(.53, .16, .39, .96) infinite;
}
.bubble:nth-child(2) {
margin-top: 3vh;
left: 52%;
width: 2vh;
height: 2vh;
background-color: lighten($color, 4%);
animation: bubble 2s ease-in-out .35s infinite;
}
.bubble:nth-child(3) {
margin-top: 1.8vh;
left: 50%;
width: 1.5vh;
height: 1.5vh;
background-color: $color;
animation: bubble 1.5s cubic-bezier(.53, .16, .39, .96) .55s infinite;
}
.bubble:nth-child(4) {
margin-top: 2.7vh;
left: 56%;
width: 1.2vh;
height: 1.2vh;
background-color: darken($color, 3%);
animation: bubble 1.8s cubic-bezier(.53, .16, .39, .96) .9s infinite;
}
.bubble:nth-child(5) {
margin-top: 2.7vh;
left: 63%;
width: 1.1vh;
height: 1.1vh;
background-color: darken($color, 6%);
animation: bubble 1.6s ease-in-out 1s infinite;
}
#area {
position: absolute;
bottom: 0;
right: 0;
width: 50%;
height: 50%;
background-color: transparent;
transform-origin: 15% 60%;
animation: flip #{$anim_time}s ease-in-out infinite;
#sides {
position: absolute;
width: 100%;
height: 100%;
transform-origin: 15% 60%;
animation: switchSide #{$anim_time}s ease-in-out infinite;
#handle {
position: absolute;
bottom: 18%;
right: 80%;
width: 35%;
height: 20%;
background-color: transparent;
border-top: 1vh solid $color;
border-left: 1vh solid transparent;
border-radius: 100%;
transform: rotate(20deg) rotateX(0deg) scale(1.3, .9);
}
#pan {
position: absolute;
bottom: 20%;
right: 30%;
width: 50%;
height: 8%;
background-color: $color;
border-radius: 0 0 1.4em 1.4em;
transform-origin: -15% 0;
}
}
#pancake {
position: absolute;
top: 24%;
width: 100%;
height: 100%;
transform: rotateX(85deg);
animation: jump #{$anim_time}s ease-in-out infinite;
#pastry {
position: absolute;
bottom: 26%;
right: 37%;
width: 40%;
height: 45%;
background-color: $color;
box-shadow: 0 0 3px 0 $color;
border-radius: 100%;
transform-origin: -20% 0;
animation: fly #{$anim_time}s ease-in-out infinite;
}
}
}
}
@keyframes jump {
0% {
top: 24%;
transform: rotateX(#{$flatten_deg}deg);
}
25% {
top: 10%;
transform: rotateX(0deg);
}
50% {
top: 30%;
transform: rotateX(#{$flatten_deg}deg);
}
75% {
transform: rotateX(0deg);
}
100% {
transform: rotateX(#{$flatten_deg}deg);
}
}
@keyframes flip {
0% {
transform: rotate(0deg);
}
5% {
transform: rotate(-#{$angle}deg);
}
30%,
50% {
transform: rotate(0deg);
}
55% {
transform: rotate(#{$angle}deg);
}
83.3% {
transform: rotate(0deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes switchSide {
0% {
transform: rotateY(0deg);
}
50% {
transform: rotateY(180deg);
}
100% {
transform: rotateY(0deg);
}
}
@keyframes fly {
0% {
bottom: 26%;
transform: rotate(0deg);
}
10% {
bottom: $peak;
}
50% {
bottom: 26%;
transform: rotate(-190deg);
}
80% {
bottom: $peak;
}
100% {
bottom: 26%;
transform: rotate(0deg);
}
}
@keyframes bubble {
0% {
transform: scale(.15, .15);
top: 80%;
opacity: 0;
}
50% {
transform: scale(1.1, 1.1);
opacity: 1;
}
100% {
transform: scale(.33, .33);
top: 60%;
opacity: 0;
}
}
@keyframes pulse {
0% {
transform: scale(1, 1);
opacity: .25;
}
50% {
transform: scale(1.2, 1);
opacity: 1;
}
100% {
transform: scale(1, 1);
opacity: .25;
}
}
+15
View File
@@ -0,0 +1,15 @@
# 🎾 Pong Pure Loader
Минималистичный индикатор загрузки, воссоздающий геймплей легендарной игры Pong. Реализовано полностью на чистом CSS.
### Особенности
- **Retro Gaming Vibe**: Классическая механика взаимодействия двух ракеток и мяча.
- **Perfect Timing**: Движения обеих ракеток (`player_one`, `player_two`) идеально синхронизированы с траекторией полета мяча.
- **Extreme Lightness**: Код занимает всего несколько десятков строк и не требует никаких внешних ресурсов или JS.
### Технические детали
- **Ball Animation**: Мяч движется по сложной траектории с использованием `linear` тайминга для имитации постоянной скорости.
- **Paddles**: Ракетки перемещаются только по оси Y (`translateY`), имитируя логику игры.
- **Layout**: Использование `position: absolute` и `transform: translate(-50%, -50%)` для идеального центрирования на экране.
+20
View File
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Pong Pure CSS Loader</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<body>
<div class="content">
<div class="player_one"></div>
<div class="player_two"></div>
<div class="ball"></div>
</div>
</body>
</body>
</html>
+80
View File
@@ -0,0 +1,80 @@
body {
background: #56c8d8;
}
.content {
position: absolute;
top: 45%;
left: 57.5%;
transform: translate(-50%, -50%);
display: block;
}
.paddle, .player_two, .player_one {
height: 40px;
width: 3px;
background-color: white;
position: relative;
}
.player_one {
left: -180px;
animation: movePaddleOne 4s infinite;
}
.player_two {
left: 20px;
animation: movePaddleTwo 4s infinite;
}
.ball {
position: relative;
height: 5px;
width: 5px;
border-radius: 50%;
background-color: white;
animation: moveBall 4s infinite linear;
}
@keyframes movePaddleOne {
0%, 100% {
transform: translate(0px, 100px);
}
25% {
transform: translate(0px, 0px);
}
50% {
transform: translate(0px, 0px);
}
75% {
transform: translate(0px, 100px);
}
}
@keyframes movePaddleTwo {
0%, 100% {
transform: translate(0px, -50px);
}
25% {
transform: translate(0px, 10px);
}
50% {
transform: translate(0px, 0px);
}
75% {
transform: translate(0px, 50px);
}
}
@keyframes moveBall {
0%, 100% {
transform: translate(-180px, 30px);
}
25% {
transform: translate(18px, -25px);
}
50% {
transform: translate(-180px, -55px);
}
75% {
transform: translate(18px, 15px);
}
}
+84
View File
@@ -0,0 +1,84 @@
body {
background: #56c8d8;
}
.content {
position: absolute;
top: 45%;
left: 57.5%;
transform: translate(-50%, -50%);
display: block;
}
.paddle{
height:40px;
width:3px;
background-color:white;
position:relative;
}
.player_one{
@extend .paddle;
left:-180px;
animation: movePaddleOne 4s infinite;
}
.player_two{
@extend .paddle;
left:20px;
animation: movePaddleTwo 4s infinite;
}
.ball{
position:relative;
height:5px;
width:5px;
border-radius:50%;
background-color:white;
animation: moveBall 4s infinite linear;
}
@keyframes movePaddleOne{
0%, 100%{
transform:translate(0px, 100px);
}
25%{
transform:translate(0px, 0px);
}
50%{
transform:translate(0px, 0px);
}
75%{
transform:translate(0px, 100px);
}
}
@keyframes movePaddleTwo{
0%, 100%{
transform:translate(0px,-50px);
}
25%{
transform:translate(0px,10px);
}
50%{
transform:translate(0px,0px);
}
75%{
transform:translate(0px,50px);
}
}
@keyframes moveBall{
0%, 100%{
transform:translate(-180px, 30px);
}
25%{
transform:translate(18px, -25px);
}
50%{
transform:translate(-180px, -55px);
}
75%{
transform:translate(18px, 15px);
}
}
+14
View File
@@ -0,0 +1,14 @@
# 🎰 Rolling Letters Loader
Креативный текстовый индикатор загрузки с эффектом «барабана». Буквы слова **LOADING** поочередно вылетают и прокручиваются по вертикали, создавая эффект динамичного каскада.
### Особенности
- **Pure CSS**: Вся магия анимации реализована через `@keyframes` и трансформации.
- **Zero JS**: Решение работает без использования JavaScript и сторонних библиотек.
- **Staggered Animation**: Эффект «волны» достигается за счет последовательной задержки (`animation-delay`) для каждого символа.
### Технологии
- **HTML5**: Семантическая разметка с использованием `<span>` для каждой буквы.
- **CSS3**: Использование `rotateX` для 3D-вращения и `top` для перемещения по вертикали.
+22
View File
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CSS Rolling Letters Loader</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<h1>
<span class="let1">l</span>
<span class="let2">o</span>
<span class="let3">a</span>
<span class="let4">d</span>
<span class="let5">i</span>
<span class="let6">n</span>
<span class="let7">g</span>
</h1>
<!-- partial -->
</body>
</html>
+86
View File
@@ -0,0 +1,86 @@
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
font-size: 100%;
background: #191a1a;
text-align: center;
}
h1 {
margin: 0;
padding: 0;
font-family: Arial Narrow, sans-serif;
font-weight: 100;
font-size: 1.1em;
color: #a3e1f0;
}
span {
position: relative;
top: 0.63em;
display: inline-block;
text-transform: uppercase;
opacity: 0;
transform: rotateX(-90deg);
}
.let1 {
animation: drop 1.2s ease-in-out infinite;
animation-delay: 1.2s;
}
.let2 {
animation: drop 1.2s ease-in-out infinite;
animation-delay: 1.3s;
}
.let3 {
animation: drop 1.2s ease-in-out infinite;
animation-delay: 1.4s;
}
.let4 {
animation: drop 1.2s ease-in-out infinite;
animation-delay: 1.5s;
}
.let5 {
animation: drop 1.2s ease-in-out infinite;
animation-delay: 1.6s;
}
.let6 {
animation: drop 1.2s ease-in-out infinite;
animation-delay: 1.7s;
}
.let7 {
animation: drop 1.2s ease-in-out infinite;
animation-delay: 1.8s;
}
@keyframes drop {
10% {
opacity: 0.5;
}
20% {
opacity: 1;
top: 3.78em;
transform: rotateX(-360deg);
}
80% {
opacity: 1;
top: 3.78em;
transform: rotateX(-360deg);
}
90% {
opacity: 0.5;
}
100% {
opacity: 0;
top: 6.94em
}
}