7.2 KiB
7.2 KiB
name, title, description, tags, source
| name | title | description | tags | source | |||||
|---|---|---|---|---|---|---|---|---|---|
| motion/animated-gradient | Animated Gradient Background | Smoothly shifting color gradients for backgrounds, buttons, and text. Creates premium, living feel. |
|
stripe.com, raycast.com, resend.com, linear.app |
Animated Gradient Background
Что это
Анимированные градиентные фоны, которые плавно перетекают друг в друга. Один из ключевых паттернов Stripe.com и современных SaaS-лендингов. Создаёт ощущение "живого" дизайна.
Типы анимированных градиентов
1. Stripe-Style (shifting color flow)
.gradient-bg {
background: linear-gradient(
135deg,
#6366f1,
#8b5cf6,
#ec4899,
#f43f5e,
#6366f1
);
background-size: 400% 400%;
animation: gradient-shift 15s ease infinite;
}
@keyframes gradient-shift {
0% { background-position: 0% 50%; }
25% { background-position: 100% 50%; }
50% { background-position: 100% 100%; }
75% { background-position: 0% 100%; }
100% { background-position: 0% 50%; }
}
2. Radial Pulse (расширяющийся круг)
.gradient-pulse {
background: radial-gradient(
circle at 30% 30%,
rgba(99, 102, 241, 0.15),
transparent 50%
);
animation: pulse 8s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.2);
opacity: 0.8;
}
}
3. Mesh Gradient (несколько источников)
.mesh-gradient {
background:
radial-gradient(ellipse at 20% 80%, rgba(99, 102, 241, 0.15), transparent 50%),
radial-gradient(ellipse at 80% 20%, rgba(236, 72, 153, 0.15), transparent 50%),
radial-gradient(ellipse at 50% 50%, rgba(139, 92, 246, 0.1), transparent 50%);
background-size: 100% 100%;
animation: mesh-move 20s ease-in-out infinite alternate;
}
@keyframes mesh-move {
0% {
background-position: 0% 0%, 100% 100%, 50% 50%;
}
100% {
background-position: 100% 100%, 0% 0%, 60% 40%;
}
}
4. Gradient Border (подвижная рамка)
.gradient-border {
position: relative;
border-radius: 20px;
padding: 2px; /* border width */
background: linear-gradient(90deg, #6366f1, #ec4899, #f43f5e, #6366f1);
background-size: 300% 100%;
animation: border-gradient 4s linear infinite;
}
.gradient-border::before {
content: '';
position: absolute;
inset: 0;
border-radius: 18px;
background: #0a0a0a;
z-index: -1;
}
@keyframes border-gradient {
0% { background-position: 0% 50%; }
100% { background-position: 100% 50%; }
}
Glassmorphism Card (Stripe style)
.glass-card {
position: relative;
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 20px;
overflow: hidden;
}
.glass-card::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.05) 0%,
transparent 50%
);
pointer-events: none;
}
Hero Gradient Background (Stripe.com style)
<section class="hero-gradient">
<div class="gradient-orb orb-1"></div>
<div class="gradient-orb orb-2"></div>
<div class="gradient-orb orb-3"></div>
<div class="hero-content">
<h1>Your text here</h1>
</div>
</section>
.hero-gradient {
position: relative;
min-height: 60vh;
overflow: hidden;
background: #0a0a0a;
}
.gradient-orb {
position: absolute;
border-radius: 50%;
filter: blur(80px);
opacity: 0.4;
animation: orb-float 20s ease-in-out infinite;
}
.orb-1 {
width: 600px;
height: 600px;
background: radial-gradient(circle, #6366f1, transparent 70%);
top: -20%;
left: -10%;
animation-delay: 0s;
}
.orb-2 {
width: 500px;
height: 500px;
background: radial-gradient(circle, #ec4899, transparent 70%);
bottom: -20%;
right: -5%;
animation-delay: -5s;
}
.orb-3 {
width: 400px;
height: 400px;
background: radial-gradient(circle, #10b981, transparent 70%);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation-delay: -10s;
}
@keyframes orb-float {
0%, 100% {
transform: translate(0, 0) scale(1);
}
25% {
transform: translate(50px, -30px) scale(1.1);
}
50% {
transform: translate(-30px, 50px) scale(0.95);
}
75% {
transform: translate(30px, 30px) scale(1.05);
}
}
Animated Button Gradient
.btn-gradient-animated {
position: relative;
padding: 14px 28px;
border: none;
border-radius: 12px;
font-weight: 600;
color: white;
cursor: pointer;
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.btn-gradient-animated::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
120deg,
#6366f1,
#8b5cf6,
#ec4899,
#f43f5e,
#6366f1
);
background-size: 300% 100%;
animation: btn-gradient 6s ease infinite;
}
.btn-gradient-animated:hover {
transform: translateY(-2px);
box-shadow: 0 8px 30px rgba(99, 102, 241, 0.3);
}
@keyframes btn-gradient {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
Color Palettes
Indie/SaaS (Stripe/Linear style)
--grad-indigo: #6366f1;
--grad-purple: #8b5cf6;
--grad-pink: #ec4899;
--grad-rose: #f43f5e;
--grad-cyan: #06b6d4;
Warm (Resend style)
--grad-orange: #f97316;
--grad-yellow: #eab308;
--grad-red: #ef4444;
--grad-pink: #ec4899;
Cool (Raycast style)
--grad-blue: #3b82f6;
--grad-cyan: #06b6d4;
--grad-teal: #14b8a6;
--grad-green: #10b981;
Anti-patterns
| ❌ Плохо | ✅ Хорошо |
|---|---|
animation: 3s — слишком быстро (мозг не успевает) |
animation: 15–30s — медленное плавное движение |
Яркие цвета #ff0000 |
Приглушённые rgba(99,102,241,0.15) |
Без filter: blur() на орбах |
blur(80–120px) для мягких переходов |
Без prefers-reduced-motion |
Уважать настройки пользователя |
| Градиент на тексте без fallback | Всегда -webkit-background-clip |
Performance
/* ✅ Good — CSS animation (GPU accelerated) */
.gradient-bg {
animation: gradient-shift 15s ease infinite;
will-change: background-position;
}
/* ❌ Bad — JS animation (main thread) */
element.animate([
{ backgroundPosition: '0% 50%' },
{ backgroundPosition: '100% 50%' }
], { duration: 15000, iterations: Infinity });
CV Service Validation
# Проверить визуальную гармонию градиентов
curl -s -X POST http://localhost:8001/design/analyze \
-H "Content-Type: application/json" \
-d '{"image_base64": "...", "full_analysis": false}' | python3 -c "
import sys, json
d = json.load(sys.stdin)
color = d['dimensions'].get('color_harmony', {})
print(f\"Color Harmony: {color.get('score', 'N/A')}/10\")
print(f\" Palette: {color.get('palette', 'N/A')}\")
"
Ожидается: color_harmony > 6.