Files

143 lines
3.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: motion/parallax-scroll
title: Parallax Depth Effect
description: Multi-layer scrolling with different speeds. Creates 3D depth perception.
tags: [motion, parallax, depth, scroll, 3d, premium]
source: 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-реализация (простая)
```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 (рекомендуется)
```javascript
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 (лёгкий вариант)
```javascript
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
```css
@media (prefers-reduced-motion: reduce) {
.parallax-layer {
transform: none !important;
}
}
```
## CV Service Validation
```bash
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\")
"
```