- 74 brands: airbnb, stripe, apple, figma, linear, vercel, etc. - 147 files: DESIGN.md + README.md per brand (~2.1 MB) - Each DESIGN.md contains structured brand analysis (colors, typography, components) - Updated 00-overview.md with new design-systems directory
3.3 KiB
3.3 KiB
name, title, description, tags, source
| name | title | description | tags | source | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| motion/parallax-scroll | Parallax Depth Effect | Multi-layer scrolling with different speeds. Creates 3D depth perception. |
|
apple.com, linear.app, amppz.com, brad.co |
Parallax Depth Effect
Что это
Многослойный скролл с разной скоростью — создаёт ощущение глубины и 3D-пространства.
Параметры
| Параметр | Значение |
|---|---|
| Foreground speed | 1x (обычный скролл) |
| Midground speed | 0.5x–0.7x |
| Background speed | 0.1x–0.3x |
CSS-реализация (простая)
.parallax-section {
position: relative;
height: 100vh;
overflow: hidden;
}
.parallax-layer {
position: absolute;
width: 100%;
height: 120%;
top: -10%;
}
.parallax-layer.background {
z-index: 1;
}
.parallax-layer.midground {
z-index: 2;
transform: translateY(10%);
}
.parallax-layer.foreground {
z-index: 3;
transform: translateY(20%);
}
GSAP ScrollTrigger (рекомендуется)
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
// Background slow
gsap.to('.parallax-bg', {
yPercent: 30,
ease: 'none',
scrollTrigger: {
trigger: '.parallax-section',
start: 'top bottom',
end: 'bottom top',
scrub: true
}
});
// Midground medium
gsap.to('.parallax-mid', {
yPercent: 50,
ease: 'none',
scrollTrigger: {
trigger: '.parallax-section',
start: 'top bottom',
end: 'bottom top',
scrub: true
}
});
// Foreground fast
gsap.to('.parallax-fg', {
yPercent: 80,
ease: 'none',
scrollTrigger: {
trigger: '.parallax-section',
start: 'top bottom',
end: 'bottom top',
scrub: true
}
});
Intersection Observer (лёгкий вариант)
const layers = document.querySelectorAll('.parallax-layer');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const speed = parseFloat(entry.target.dataset.speed || 0.1);
const rect = entry.target.getBoundingClientRect();
const scrollPercent = window.scrollY / (window.innerHeight + rect.height);
entry.target.style.transform = `translateY(${scrollPercent * speed * 100}%)`;
});
}, { threshold: 0.1 });
layers.forEach(layer => observer.observe(layer));
Anti-patterns
| ❌ Плохо | ✅ Хорошо |
|---|---|
Без prefers-reduced-motion |
Уважать настройки пользователя |
yPercent: 100 — слишком резко |
yPercent: 30–50 |
Без scrub: true |
scrub: 1 для плавности |
| 太重ых элементов | SVG/градиенты вместо фото |
Mobile
@media (prefers-reduced-motion: reduce) {
.parallax-layer {
transform: none !important;
}
}
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)
motion = d['dimensions'].get('motion_quality', {})
print(f\"Motion Quality: {motion.get('score', 'N/A')}/10\")
"