Roomify: Implementace AI vizualizátoru interiérů s React a serverless Puter
Roomify převádí 2D půdorys místnosti na fotorealistický 3D render během vteřin. Aplikace využívá React 19 s TypeScriptem pro frontend a platformu Puter pro serverless logiku, ukládání dat a AI generování. Bez vlastního backendu frontend přímo komunikuje s Puter API prostřednictvím SDK puter.js.
Architektura vylučuje tradiční server: nahrávání souborů, vytváření projektů a volání AI probíhá v workers. To zjednodušuje nasazení a škálování pro středně pokročilé a senior vývojáře.
Technologický stack a jeho role
- React 19 + TypeScript: typizovaný frontend s HMR přes Vite.
- React Router 7: routy pro hlavní stránku a vizualizátor.
- Tailwind CSS: utilitární styly bez vlastního CSS.
- Lucide React: ikony pro UI.
- Puter.js: přístup k úložišti souborů, KV, workers a AI modelům přímo z prohlížeče.
Puter poskytuje serverless workers, KV úložiště a trvalé úložiště souborů. Workers se volají přes puter.action, AI přes puter.ai.generate.
Architektura: od nahrání po render
Proces zpracování:
- Nahrání půdorysu do
puter.file.write. - Získání veřejné URL souboru.
- Volání workeru
project.createpro zápis metadat do KV. - Generování přes worker
ai.render3d: načtení obrázku, sestavení promptu, volání Claude/Gemini, uložení výsledku. - Aktualizace KV s URL renderu a vrácení na frontend.
Frontend zobrazuje původní půdorys a render pomocí react-compare-slider pro porovnání.
Worker funkce: kód a logika
Funkce workers v JavaScriptu se nahrávají přes Puter CLI.
Vytvoření projektu:
// lib/puter.action.ts
export async function createProject({ item, visibility }) {
const result = await puter.action('project.create', {
item,
visibility,
});
return result;
}
export async function getProjects() {
return await puter.action('project.list');
}
export async function getProjectById({ id }) {
return await puter.action('project.get', { id });
}
Generování renderu:
// worker: ai.render3d
export default async ({ sourceImage, style = 'photorealistic' }) => {
const imageUrl = typeof sourceImage === 'string' ? sourceImage : await puter.file.url(sourceImage);
const prompt = `
Transform this floor plan into a ${style} 3D interior render.
The image shows a room layout with walls, windows, and doors.
Generate a realistic view from a perspective that best showcases the space.
Add appropriate furniture, textures, lighting, and shadows.
Make it look like a professional architectural visualization.
`;
const result = await puter.ai.generate({
model: 'claude-3-sonnet',
prompt,
images: [imageUrl],
responseFormat: 'image'
});
const renderedPath = `/projects/${projectId}/rendered.png`;
await puter.file.write(renderedPath, result.image);
const key = `project:${projectId}`;
const project = JSON.parse(await puter.kv.get(key));
project.renderedImage = puter.file.url(renderedPath);
await puter.kv.set(key, JSON.stringify(project));
return {
renderedImage: project.renderedImage,
renderedPath
};
};
KV ukládá metadata: název projektu, vlastník, soukromí, odkazy na soubory.
Frontend: komponenty a hooky
Hlavní stránka (Home) zobrazuje seznam projektů. Komponenta Upload převádí soubor do base64:
// components/Upload.tsx
const handleFileChange = async (e) => {
const file = e.target.files[0];
if (!file) return;
const base64 = await toBase64(file);
onComplete(base64);
};
Vizualizátor (VisualizerId) používá useEffect pro automatické generování:
useEffect(() => {
if (isProjectLoading || hasInitialGenerated.current || !project?.sourceImage) return;
if (project.renderedImage) {
setCurrentImage(project.renderedImage);
hasInitialGenerated.current = true;
return;
}
hasInitialGenerated.current = true;
void runGeneration(project);
}, [project, isProjectLoading]);
useRef zabraňuje opakovaným voláním. Stav je lokální, bez Reduxu.
Řešení typických problémů
- CORS: proxy Vite ve vývoji.
- Velikost base64: uložení souboru zvlášť, odkaz v KV.
- Dvojité generování:
useRef+ kontroly. - Asynchronita: stavy načítání, skeleton komponenty.
- Mobilní UI: responzivní Tailwind, dotykové ovládání slideru.
Validace: soubory do 10 MB, JPG/PNG. Loadery pro 10-15 sekund generování.
Co je důležité
- Puter nahrazuje backend: workers, KV, soubory, AI v jednom SDK.
- React hooky spravují stav bez externích knihoven.
- Prompt určuje kvalitu: detail stěn, nábytku, osvětlení.
- Architektura je škálovatelná pro produkci bez DevOps.
- Kód je otevřený, vhodný pro forky a experimenty.
— Editorial Team
Zatím žádné komentáře.