studiophotoeditDémonstration interactive ↗

Votre éditeur, dans votre site.

Hébergez l’atelier sur votre serveur et pilotez-le dans une iframe. L’édition se déroule dans le navigateur.

Dans une iframe, seul l’aperçu est affiché : aucun bouton, menu, sélection au clic, raccourci d’édition ou dépôt de fichier. Les ouvertures, modifications et exports passent exclusivement par l’API. Le SDK active ce mode automatiquement. L’URL /?mode=api permet aussi de vérifier cet affichage seul ; l’URL sans paramètre, ouverte directement, conserve l’éditeur complet.

Autoriser Lovable

Dans studio.config.json, parentOrigins accepte des origines exactes et des jokers de sous-domaines, par exemple https://lovable.dev, https://*.lovable.dev, https://*.lovable.app et https://*.lovableproject.com. Ils autorisent à la fois l’affichage iframe et les commandes API depuis ces domaines. Un joker autorise tous les projets du domaine concerné et ne couvre pas le domaine racine. Après modification, exécutez python3 configure.py puis rechargez Nginx. Les réponses restent envoyées uniquement à l’origine exacte de la fenêtre parente. assetOrigins conserve des origines exactes.

Installer l’intégration

Copiez sdk.js sur le site intégrateur. Autorisez son origine dans la configuration de votre déploiement, puis utilisez votre URL d’éditeur :

<iframe id="studio" title="Éditeur"></iframe>
<script type="module">
import { StudioClient } from '/js/studio-sdk.js';
const studio = new StudioClient(
  document.querySelector('#studio'),
  'https://studio.example.com/'
);
await studio.ready;
await studio.run('app.documents.add(800,600,72,"Image");');
const bytes = await studio.export('psd');
</script>

Photos et objets dynamiques

Documentation complète : remplacer une photo dans un PSD via l’API, avec exemple Lovable et objets imbriqués.

Ouvrir et enregistrer vos fichiers

const bytes = await file.arrayBuffer();
await studio.open(bytes);
await studio.run('app.activeDocument.layers.getByName("Titre").textItem.contents = "Bonjour";');
const updated = await studio.export('psd');
// Le chemin, l’authentification et le stockage appartiennent à votre backend.
await fetch('/mon-endpoint', { method: 'POST', body: updated });

Protocole iframe

Commandes disponibles

CommandeEffet
app.documents.add(w,h,72,name)Créer un document ; remplace le document courant.
app.activeDocument.addText(text,x,y,size,"#RRGGBB")Ajouter un texte éditable.
app.activeDocument.layers.getByName(name)Accéder à un calque, y compris dans un groupe.
layer.textItem.contents / sizeLire ou modifier le texte / sa taille.
layer.name / visible / opacityModifier les propriétés ; opacité de 0 à 100.
layer.translate(x,y)Déplacer le calque ou le groupe.
layer.setDropShadow(color,opacity,distance,blur)Régler l’ombre portée.
layer.setColorOverlay(color,opacity)Régler l’incrustation de couleur.
doc.activeLayer = doc.layers.getByName(name)Sélectionner un calque.
doc.addGroup(name)Créer un groupe.
doc.addMask() / invertMask()Ajouter / inverser le masque du calque actif.
doc.addAdjustment(brightness,contrast)Créer un calque de réglage.
doc.resizeImage(w,h) / rotateCanvas(90)Transformer le document.
doc.crop([left,top,right,bottom])Recadrer.
doc.saveToOE(format)Exporter PNG, JPG, WebP, PSD, SPHOTO ou le PSD original.
doc.sourceLire / définir votre identifiant de document.

doc désigne app.activeDocument. Le moteur accepte variables, accès aux propriétés, appels, conditions et boucles for bornées. Les fonctions arbitraires, window, eval, les imports et le réseau dans un script sont interdits. Une commande non prise en charge échoue explicitement.

Configuration initiale

Le SDK accepte {config:{files:[url],script:"…"}} comme troisième paramètre. Il encode ce JSON dans le fragment de l’URL. Un seul fichier initial est pris en charge. Les URL de fichiers doivent provenir du même site ou des origines explicitement autorisées ; le transfert binaire depuis le parent évite cette contrainte.

Les paramètres server, environment et apis d’autres éditeurs ne sont pas implémentés. La compatibilité porte sur les commandes décrites ici, pas sur toute une API tierce.

Conserver l’éditabilité

Les groupes, textes, masques, styles et objets incorporés restent structurés. Certains rendus avancés sont encore incomplets : consultez les limites de l’éditeur. Le projet SPHOTO conserve aussi l’original PSD et le modèle édité.

Polices

Les polices du catalogue sont hébergées sur votre serveur et chargées à la demande. Utilisez leur nom PostScript.

app.activeDocument.activeLayer.textItem.font = "Arabela-Regular";
app.activeDocument.addText("Bonjour", 30, 30, 48, "#111111", "Arabela-Regular");
app.echoToOE(JSON.stringify(app.listFonts()));

Vous pouvez envoyer une police TTF/OTF en ArrayBuffer par postMessage (ou client.open), sans remplacer le document. La configuration resources accepte une liste d’URL de polices ; app.loadFontURL(url) permet leur chargement par script. Les URL doivent respecter assetOrigins et CORS. Les imports ponctuels restent disponibles pour la session ; renvoyez-les après rechargement.