Розробка мобільного додатку для коллажів та фотоальбомів
Додаток для коллажів — це інтерактивний редактор зображень в реальному часі. Користувач тягне фото на шаблон, масштабує, обертає, накладає текст. Якщо рендеринг гальмує при жестах — це миттєво ощущується. Весь UI повинен будуватись на GPU, а не на CPU.
Canvas: як не гальмувати при маніпуляціях
iOS. Не використовуємо UIImageView для кожного шару — це Core Animation без GPU-прискорення трансформацій при transform. Правильний шлях: CALayer ієрархія або Metal-рендеринг через MTKView.
Для більшості коллажів (до 10-15 шарів) достатньо CALayer: кожен елемент — окремий sublayer з contents = CGImage. Трансформації через CATransform3D виконуються на GPU. CATiledLayer — для великих фонів.
При фіналному рендері в файл: UIGraphicsImageRenderer з beginImageContextWithOptions або Metal-pipeline для точного відтворення трансформацій.
Android. Canvas-підхід на SurfaceView або TextureView — працює, але складно управляти шарами. Краще: кастомний View з drawBitmap + матриця трансформації для кожного елемента. Для складних ефектів — RenderScript (deprecated) або OpenGL ES через GLSurfaceView. В Jetpack Compose: Canvas Composable з drawImage(paint = ...) — швидко для простих випадків.
Flutter. CustomPainter з canvas.drawImageRect для зображень, canvas.drawParagraph для тексту. При великій кількості шарів — RepaintBoundary обертає кожен редагований елемент, Flutter перерисовує лише змінений шар.
Жесты: масштаб, обертання, перетаскування одночасно
Одночасна обробка pinch + rotate + pan — стандартна задача, але реалізувати правильно непросто.
iOS: UIPinchGestureRecognizer, UIRotationGestureRecognizer, UIPanGestureRecognizer працюють одночасно через shouldRecognizeSimultaneouslyWith. Застосовуємо дельту кожного жесту до CATransform3D елемента інкрементально — не абсолютне значення, а зміна за кадр. Інакше при початку нового жесту елемент «стрибає».
Android: ScaleGestureDetector + RotationGestureDetector (немає в стандартній бібліотеці, реалізуємо вручну через два дотику) + GestureDetector. Flutter: GestureDetector з onScaleUpdate об'єднує scale + rotation в одному колбеку (ScaleUpdateDetails.rotation).
Snap-to-grid та snap-to-center: при перетаскуванні перевіряємо proximity до осей (±10dp) та до центру canvas — якщо близко, «притягуємо» з haptic feedback (UIImpactFeedbackGenerator.impactOccurred() / performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)).
Шаблони коллажів
Шаблон визначає: кількість ячейок, їх розташування та соотношення сторін. Зберігаємо як JSON: масив {x, y, width, height, rotation} в одиницях від 0 до 1 (відносно розміру коллажу). При відображенні масштабуємо під розмір екрану.
Користувач заповнює ячейки фото з галереї. PHPickerViewController (iOS 14+) / PhotoPicker (Android) / image_picker (Flutter) — сучасні picker без запиту дозволів на всю галерею.
Fit vs Fill для ячейки: користувач обирає, обрізується ли фото під ячейку або вписується з полями.
Експорт
Фіналний коллаж рендеримо офлайн в розрішенні 2x-3x від екрану (для друку — 300 DPI для заданого фізичного розміру). Прогрес рендерингу показуємо через Progress/ProgressBar. Збереження в Photos: PHPhotoLibrary.performChanges (iOS) / MediaStore.Images.Media.insertImage (Android).
Строки: базовий редактор з 10-15 шаблонами, текстом та експортом — 3-4 тижні. Повний редактор зі стікерами, фільтрами, кастомними шаблонами та хмарним сховищем — 6-8 тижнів.







