295 lines
15 KiB
Markdown
295 lines
15 KiB
Markdown
# Визуализация новой галереи портфолио
|
||
|
||
## Структура страницы портфолио (Desktop)
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ SmartSolTech │
|
||
│ Главная > Портфолио > Название проекта │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ [Badge: Web] [Badge: E-commerce] [Badge: Mobile] │
|
||
│ │
|
||
│ Название проекта │
|
||
│ 👤 Клиент: ООО "Компания" │
|
||
│ 📅 Дата завершения: 15.11.2024 │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌──────┬──────────────────────────────────────────────────────────┐
|
||
│ IMG1 │ │
|
||
│[✓] │ │
|
||
│──────│ ◀ ▶ │
|
||
│ IMG2 │ │
|
||
│ │ ГЛАВНОЕ ИЗОБРАЖЕНИЕ │
|
||
│──────│ │
|
||
│ IMG3 │ (600px height) │
|
||
│ │ │
|
||
│──────│ │
|
||
│ IMG4 │ [🔍 Изображение 1 из 5] │
|
||
│ │ "Подпись к фото" │
|
||
└──────┴──────────────────────────────────────────────────────────┘
|
||
120px Flex: 1
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ О проекте │
|
||
│ │
|
||
│ Lorem ipsum dolor sit amet, consectetur adipiscing elit... │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
[← Все проекты]
|
||
```
|
||
|
||
## Структура на мобильных устройствах
|
||
|
||
```
|
||
┌─────────────────────────────┐
|
||
│ [Badge] [Badge] │
|
||
│ │
|
||
│ Название проекта │
|
||
│ 👤 Клиент | 📅 Дата │
|
||
└─────────────────────────────┘
|
||
|
||
┌─────────────────────────────┐
|
||
│ [IMG1][IMG2][IMG3][IMG4]>>> │ ← Горизонтальный скролл
|
||
└─────────────────────────────┘
|
||
|
||
┌─────────────────────────────┐
|
||
│ │
|
||
│ ◀ ▶ │
|
||
│ │
|
||
│ ГЛАВНОЕ ИЗОБРАЖЕНИЕ │
|
||
│ │
|
||
│ (400px) │
|
||
│ │
|
||
│ [🔍 Изображение 1 из 5] │
|
||
│ "Подпись к фото" │
|
||
└─────────────────────────────┘
|
||
|
||
┌─────────────────────────────┐
|
||
│ О проекте │
|
||
│ │
|
||
│ Описание проекта... │
|
||
│ │
|
||
└─────────────────────────────┘
|
||
```
|
||
|
||
## Интерактивные элементы
|
||
|
||
### 1. Thumbnails (миниатюры)
|
||
```
|
||
┌──────┐
|
||
│ IMG1 │ ← Неактивная (opacity: 0.6)
|
||
└──────┘
|
||
|
||
┌──────┐
|
||
│ IMG2 │ ← Активная (border: 3px blue, opacity: 1)
|
||
└──────┘
|
||
▲
|
||
│ Hover: scale(1.05)
|
||
```
|
||
|
||
### 2. Навигация
|
||
```
|
||
Клавиатура: ← → (Arrow keys)
|
||
Мышь: ▲ ▼ (Scroll wheel)
|
||
Касание: ← → (Swipe gestures)
|
||
Кнопки: ◀ ▶ (Click buttons)
|
||
```
|
||
|
||
### 3. Lightbox (увеличение)
|
||
```
|
||
Клик по изображению → Открывается полноэкранный просмотр
|
||
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ ✕ │
|
||
│ │
|
||
│ ◀ ▶ │
|
||
│ │
|
||
│ ПОЛНОЭКРАННОЕ ФОТО │
|
||
│ │
|
||
│ │
|
||
│ Изображение 3 из 5 │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Изменения в админке
|
||
|
||
### Было (одна категория):
|
||
```
|
||
┌─────────────────────────────────┐
|
||
│ Категория: [Выпадающий список ▼]│
|
||
│ ───────────────── │
|
||
│ │ Web Design │ │
|
||
│ │ Mobile App │ │
|
||
│ │ E-commerce │ │
|
||
│ ───────────────── │
|
||
└─────────────────────────────────┘
|
||
```
|
||
|
||
### Стало (множественные категории):
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ Категории: │
|
||
│ │
|
||
│ Доступные категории Выбранные категории │
|
||
│ ┌───────────────┐ ┌────────────────┐ │
|
||
│ │ Mobile App │ ⇨ │ Web Design │ │
|
||
│ │ SEO │ │ E-commerce │ │
|
||
│ │ Marketing │ ⇦ │ UI/UX │ │
|
||
│ │ Consulting │ └────────────────┘ │
|
||
│ └───────────────┘ │
|
||
│ │
|
||
│ Подсказка: Двойной клик или стрелки для выбора │
|
||
└──────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Галерея изображений (Inline):
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ Галерея изображений (3 фото): │
|
||
│ │
|
||
│ ┌────────────────────────────────────────────────────┐ │
|
||
│ │ Изображение │ Подпись │ Порядок │ 🗑️ │ │
|
||
│ ├────────────────────────────────────────────────────┤ │
|
||
│ │ [Выбрать файл]│ "Главная страница"│ 0 │ - │ │
|
||
│ │ [Выбрать файл]│ "Каталог товаров" │ 10 │ - │ │
|
||
│ │ [Выбрать файл]│ "Корзина" │ 20 │ - │ │
|
||
│ └────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ [+ Добавить еще изображение] │
|
||
└──────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Пользовательский опыт
|
||
|
||
### Сценарий 1: Desktop пользователь
|
||
1. Открывает страницу проекта
|
||
2. Видит миниатюры слева, главное фото справа
|
||
3. Клик по миниатюре → фото меняется
|
||
4. Или использует стрелки ◀ ▶
|
||
5. Или нажимает клавиши ← →
|
||
6. Или крутит колесо мыши
|
||
7. Клик по главному фото → открывается Lightbox
|
||
8. В Lightbox переключает фото стрелками
|
||
|
||
### Сценарий 2: Mobile пользователь
|
||
1. Открывает страницу проекта
|
||
2. Видит миниатюры сверху (горизонтальная полоса)
|
||
3. Свайпит влево → следующее фото
|
||
4. Свайпит вправо → предыдущее фото
|
||
5. Или тапает по миниатюре
|
||
6. Или использует кнопки ◀ ▶
|
||
7. Тап по главному фото → Lightbox
|
||
8. В Lightbox свайпит для навигации
|
||
|
||
### Сценарий 3: Администратор
|
||
1. Заходит в админку портфолио
|
||
2. Создает новый проект или редактирует существующий
|
||
3. В поле "Категории" выбирает несколько категорий:
|
||
- Web Design
|
||
- E-commerce
|
||
- UI/UX
|
||
4. Загружает главное изображение
|
||
5. Добавляет 5 дополнительных фото в галерею:
|
||
- Каждому фото дает подпись
|
||
- Устанавливает порядок: 0, 10, 20, 30, 40
|
||
6. Сохраняет
|
||
7. Открывает страницу проекта на сайте
|
||
8. Видит все категории как badges
|
||
9. Видит галерею с навигацией
|
||
10. Тестирует свайпы на планшете
|
||
|
||
## Адаптивность
|
||
|
||
### Desktop (> 768px):
|
||
- Thumbnails: вертикально слева (120px width)
|
||
- Main image: 600px height
|
||
- Navigation buttons: 50x50px
|
||
- Grid layout: Flex row
|
||
|
||
### Tablet (768px):
|
||
- Thumbnails: горизонтально сверху
|
||
- Main image: 400px height
|
||
- Navigation buttons: 40x40px
|
||
- Grid layout: Flex column-reverse
|
||
|
||
### Mobile (< 768px):
|
||
- Thumbnails: 80x80px each
|
||
- Main image: 400px height
|
||
- Navigation buttons: 40x40px
|
||
- Swipe sensitivity: 50px threshold
|
||
- Touch-friendly buttons
|
||
|
||
## Технические особенности
|
||
|
||
### Performance оптимизации:
|
||
```python
|
||
# В views.py
|
||
item = get_object_or_404(
|
||
PortfolioItem.objects.prefetch_related(
|
||
'categories', # ← Предзагрузка категорий
|
||
'gallery_images' # ← Предзагрузка галереи
|
||
),
|
||
slug=slug,
|
||
is_active=True
|
||
)
|
||
```
|
||
|
||
### CSS transitions:
|
||
```css
|
||
.thumbnail-item {
|
||
transition: all 0.3s ease; /* ← Плавная анимация */
|
||
}
|
||
|
||
.hover-zoom:hover {
|
||
transform: scale(1.05); /* ← Увеличение при hover */
|
||
}
|
||
```
|
||
|
||
### JavaScript debouncing:
|
||
```javascript
|
||
// Wheel event с preventDefault для предотвращения
|
||
// конфликта со скроллом страницы
|
||
galleryMain.addEventListener('wheel', (e) => {
|
||
if (Math.abs(e.deltaY) > 10) {
|
||
e.preventDefault();
|
||
// ... navigation logic
|
||
}
|
||
}, { passive: false });
|
||
```
|
||
|
||
### Touch gestures:
|
||
```javascript
|
||
const swipeThreshold = 50; // 50px минимум для свайпа
|
||
|
||
function handleSwipe() {
|
||
const swipeDistance = touchStartX - touchEndX;
|
||
|
||
if (Math.abs(swipeDistance) > swipeThreshold) {
|
||
// Обработка свайпа
|
||
}
|
||
}
|
||
```
|
||
|
||
## Безопасность
|
||
|
||
1. **XSS защита**:
|
||
- Caption экранируется Django templates
|
||
- `{{ gallery_image.caption }}` auto-escapes HTML
|
||
|
||
2. **CSRF**:
|
||
- Все формы админки защищены CSRF токенами
|
||
|
||
3. **Права доступа**:
|
||
- Только авторизованные админы могут добавлять портфолио
|
||
- Публичный доступ только к `is_active=True` проектам
|
||
|
||
## Масштабируемость
|
||
|
||
- ✅ Поддержка неограниченного количества категорий
|
||
- ✅ Поддержка неограниченного количества фото в галерее
|
||
- ✅ Lazy loading возможен в будущем (добавить `loading="lazy"`)
|
||
- ✅ CDN для Lightbox (не нагружает сервер)
|
||
- ✅ Кэширование статики через Nginx
|