Your photos. Your story. One PDF.
Lumiflow is a cutting-edge, zoneless Angular application designed to curate, arrange, and export high-resolution photo grids into A4 PDFs. Built for performance and privacy, it performs all image processing client-side.
- ✨ Key Features
- 🔧 Dependencies & Versions
- 🏗 Architecture & Design
- 💻 Installation & Setup
- 📱 Usage Guide
- 🧠 Technical Highlights
- 🛣 Roadmap
- Smart 2x2 Grid System: Automatically calculates layout matrices to fit 4 photos per A4 page perfectly.
- Dynamic Pagination: Seamlessly adds new pages as you upload more photos (4, 8, 12... unlimited).
- Drag & Drop Editing:
- Pan: Click and drag inside a cell to reposition the image.
- Resize: Use 8-point handle controls to scale images with precision.
- Aspect Ratio Locking: Smart scaling preserves image quality.
- Reordering: Intuitive "Move Left" and "Move Right" controls to swap image positions across the grid.
- Client-Side Rendering: Generates PDFs directly in the browser using
jsPDF. No server required. - Margin Modes:
- Narrow Margins (Default): Optimized 6mm outer / 4mm gap for a crisp, professional look.
- No Margins: Maximizes image size with minimal 5mm printer-safe edges.
- Global Stretch: Optional mode to force all images to fill their grid cells entirely.
- Local Processing: Images are processed via HTML5 Canvas and
FileReaderlocally. Zero data upload. - Image Optimization: Automatic downscaling of massive images to 1500px max dimension to prevent browser crashes and reduce PDF size while maintaining print quality.
- Zoneless Rendering: Built with
provideZonelessChangeDetection()for next-gen Angular performance.
This project leverages the latest web technologies.
| Dependency | Version | Purpose |
|---|---|---|
| Angular | ^21.1.0 |
Core Framework (Zoneless, Signals) |
| TypeScript | ~5.x |
Static Typing |
| RxJS | ^7.8.2 |
Reactive Streams (Drag logic, file reading) |
| Tailwind CSS | 3.4 (CDN) |
Utility-first Styling |
| jsPDF | 2.5.1 |
PDF Generation Engine |
| Google Fonts | Inter & Poppins |
Typography |
Lumiflow follows a Service-Based, Signal-Driven architecture.
src/
├── app.component.ts # Root Orchestrator (Modal handling, global layout)
├── services/
│ ├── app-state.service.ts # Single Source of Truth (Signals)
│ ├── pdf-generator.service.ts # Mathematical logic for PDF coordinates
│ └── image-processor.service.ts # Canvas manipulation & Base64 encoding
├── components/
│ ├── header/ # Global Settings & Actions
│ ├── splash/ # Intro Animations (CSS Keyframes)
│ ├── setup/ # Initial Configuration Form
│ └── workspace/ # The Core Editor (Grids, Drag Logic)
└── index.html # SEO, Meta Tags, Tailwind Injection
- AppStateService: Holds the state (
images,settings) in Signals. - Computed Signals: Derived state (e.g.,
pagesarray calculated from linearimagesarray) updates automatically. - OnPush Components: All components use
ChangeDetectionStrategy.OnPushfor maximum efficiency. - RxJS Interop: Used primarily for complex DOM events (Drag & Drop streams) and File Reading, bridging back to Signals for UI updates.
- Node.js v18 or higher
- NPM v9 or higher
-
Clone the Repository
git clone https://github.com/your-username/lumiflow.git cd lumiflow -
Install Dependencies
npm install
-
Run Development Server
npm start
Open
http://localhost:4200in your browser. -
Build for Production
npm run build
Artifacts will be stored in
dist/.
- Welcome Screen: Wait for the animation to complete and click "Dive In".
- Setup: Select the number of photos you want to arrange (e.g., 4, 8, 12).
- Upload: Click any "+" slot to upload images. You can select multiple files at once.
- Edit:
- Click "Adjust Size" on an image.
- Drag corners to resize. Drag center to move.
- Click "Done" to save.
- Configure: Use the top bar to toggle "No Margins" or "Global Stretch".
- Export: Click "Export PDF" to download your file.
The PdfGeneratorService treats the A4 page (210mm x 297mm) as a coordinate system.
- Logic: Iterates through the
imagesarray. - Math: Calculates
x, y, width, heightbased on:- Current Column (0 or 1)
- Current Row (0 or 1)
- Selected Margin (6mm vs 5mm)
- Grid Gap (4mm vs 0mm)
- Customization: If a user manually resizes an image in the UI, those percentage-based values (
customWidth,customX) are projected onto the PDF cell dimensions mathematically.
The drag logic in WorkspaceComponent uses RxJS streams (fromEvent, switchMap, takeUntil) to handle mouse and touch events outside of the Angular zone where possible, only updating the specific Signal (updateImageById) on frame updates to ensure smooth 60fps interactions on mobile devices.
- Filters & Effects: Add grayscale, sepia, and brightness controls.
- Custom Grid Layouts: Support for 1x1, 3x3, and collage layouts.
- Text Captions: Allow users to add text descriptions below photos.
- PWA Support: Install Lumiflow as a native app on iOS/Android.
- Cloud Sync (Optional): Save sessions to LocalStorage or Firebase.