Retour à l'accueil

Roomify : rendu d'intérieur IA sur React Puter

Roomify — application web pour générer des rendus d'intérieur 3D à partir de plans 2D en utilisant React et Puter. Architecture sur workers sans serveur élimine le backend. Code workers fourni, hooks frontend et solutions de problèmes.

Créez un visualiseur IA comme Roomify sur React+Puter
Advertisement 728x90

Roomify : Créer un visualiseur d'intérieur IA avec React et Puter serverless

Roomify transforme un plan 2D en rendu 3D photoréaliste en quelques secondes. L'application utilise React 19 avec TypeScript pour le frontend et la plateforme Puter pour la logique serverless, le stockage et la génération IA. Sans backend personnalisé, le frontend interagit directement avec l'API Puter via le SDK puter.js.

L'architecture élimine le serveur traditionnel : les téléchargements de fichiers, la création de projets et les appels IA s'effectuent dans des workers. Cela simplifie le déploiement et la mise à l'échelle pour les développeurs intermédiaires et seniors.

Stack technique et leurs rôles

  • React 19 + TypeScript : Un frontend typé avec HMR via Vite.
  • React Router 7 : Routes pour la page d'accueil et le visualiseur.
  • Tailwind CSS : Stylage utility-first sans CSS personnalisé.
  • Lucide React : Icônes pour l'interface utilisateur.
  • Puter.js : Accès au stockage de fichiers, KV, workers et modèles IA depuis le navigateur.

Puter fournit des workers serverless, un stockage KV et un stockage de fichiers persistant. Les workers sont appelés via puter.action, et l'IA via puter.ai.generate.

Google AdInline article slot

Architecture : Du téléchargement au rendu

Flux de traitement :

  • Télécharger le plan vers puter.file.write.
  • Obtenir une URL publique pour le fichier.
  • Appeler le worker project.create pour écrire les métadonnées dans KV.
  • Générer via le worker ai.render3d : charger l'image, créer un prompt, appeler Claude/Gemini, sauvegarder le résultat.
  • Mettre à jour KV avec l'URL du rendu et retourner au frontend.

Le frontend affiche le plan original et le rendu en utilisant react-compare-slider pour la comparaison.

Fonctions Worker : Code et logique

Les fonctions worker en JavaScript sont téléchargées via la CLI Puter.

Google AdInline article slot

Création d'un projet :

// 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 });
}

Génération d'un rendu :

// worker: ai.render3d
export default async ({ sourceImage, style = 'photorealistic' }) => {
  const imageUrl = typeof sourceImage === 'string' ? sourceImage : await puter.file.url(sourceImage);
  
  const prompt = `
    Transformez ce plan en un rendu 3D d'intérieur ${style}.
    L'image montre un agencement de pièce avec murs, fenêtres et portes.
    Générez une vue réaliste depuis une perspective qui met le mieux en valeur l'espace.
    Ajoutez des meubles, des textures, un éclairage et des ombres appropriés.
    Faites en sorte que cela ressemble à une visualisation architecturale professionnelle.
  `;
  
  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 stocke les métadonnées : nom du projet, propriétaire, confidentialité et liens de fichiers.

Google AdInline article slot

Frontend : Composants et hooks

La page d'accueil (Home) affiche une liste de projets. Le composant Upload convertit un fichier en base64 :

// components/Upload.tsx
const handleFileChange = async (e) => {
  const file = e.target.files[0];
  if (!file) return;
  const base64 = await toBase64(file);
  onComplete(base64);
};

Le visualiseur (VisualizerId) utilise useEffect pour la génération automatique :

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 empêche les appels en double. L'état est local, sans Redux.

Résolution des problèmes courants

  • CORS : Proxy Vite en développement.
  • Taille Base64 : Sauvegarder le fichier séparément, stocker le lien dans KV.
  • Double génération : useRef + vérifications.
  • Asynchronicité : États de chargement, squelettes.
  • UI mobile : Réactivité Tailwind, support tactile pour le slider.

Validation : fichiers jusqu'à 10 Mo, JPG/PNG. Loaders pour des temps de génération de 10-15 secondes.

Points clés à retenir

  • Puter remplace le backend : workers, KV, fichiers et IA dans un seul SDK.
  • Les hooks React gèrent l'état sans bibliothèques externes.
  • Les prompts définissent la qualité : détaillez les murs, les meubles et l'éclairage.
  • L'architecture est évolutive pour la production sans DevOps.
  • Le code est open-source, adapté aux forks et expérimentations.

— Editorial Team

Advertisement 728x90

Lire ensuite