Zpět na domů

Roomify: AI-render interiérů na React Puter

Roomify — webová aplikace pro generování 3D-renderů interiérů z 2D půdorysů s využitím React a Puter. Architektura na serverless workers eliminuje backend. Uvedeny kódy workers, frontend hooky a řešení problémů.

Vytvořte AI-vizualizátor jako Roomify na React+Puter
Advertisement 728x90

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.

Google AdInline article slot

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.create pro 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.

Google AdInline article slot

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.

Google AdInline article slot

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

Advertisement 728x90

Číst dál