Appearance
Adapter une app au vertical
Le runtime overlay V2 héberge les apps en SDK app V1 comme V2. Il donne le cadre disponible ; l'app choisit sa présentation. Le SDK ne déplace pas vos boutons, votre caméra ou votre terrain de jeu. Les API kapp.overlay.layout, LAYOUT_CHANGED et resolveArea présentées ici appartiennent au SDK app V2.
Le channel utilisé pour la recette doit avoir la feature Overlay multiformat (overlay_multiformat) autorisée dans Admin → Channel → Features. Elle est fermée par défaut. Recharger les overlays et aperçus après un changement d'autorisation, y compris dans le DEV HUB. Sans cette feature, la surface demande le format horizontal et les widgets restent horizontaux ; les placements verticaux enregistrés sont conservés. Une app déclarée uniquement verticale garde néanmoins son seul format : le runtime n'invente jamais de format non déclaré.
Déclarer le format après adaptation
Dans infos.json :
json
{
"overlay-formats": ["16:9", "9:16"]
}overlay-formats est la seule déclaration des formats supportés. Absente, elle vaut historiquement ["16:9"]. Présente, sa liste est respectée, sans ajout automatique de 16:9 : ["9:16"] est donc valide pour une app uniquement verticale. Le format de la surface est choisi s'il est déclaré ; sinon, le premier format de la liste est conservé, réduit et centré dans la sortie disponible. Une liste vide, null ou un format inconnu sont des erreurs de manifeste.
L'iframe remplit toujours le cadre du format choisi, à l'origine : 1920 × 1080 en horizontal, 1080 × 1920 en vertical. Sa taille et sa position ne se déclarent pas dans le manifeste. L'app organise son contenu à l'intérieur. Une popout ou un aperçu overlay DEV HUB démarre aux dimensions du premier format déclaré (horizontal si la déclaration est absente).
L'ancien champ window est accepté mais ignoré, quel que soit son contenu : il ne change plus la taille de l'iframe, son placement ni les dimensions initiales d'une popout. Il peut être supprimé des manifestes existants. Les anciennes apps sans overlay-formats disposent désormais du cadre horizontal complet ; celles qui dépendaient de leur petite fenêtre doivent appliquer ces dimensions à un conteneur interne.
Le bootstrap des nouvelles apps déclare seulement overlay-formats: ["16:9"] pour sa géométrie. Déclarez seulement les formats réellement adaptés et testés. Une ancienne app en SDK app V1 sans déclaration reste dans le cadre horizontal ; ses médias et son interface ne deviennent pas automatiquement verticaux. Ni le SDK app V1 ni le SDK app V2 n'exigent infos.window dans leur message de démarrage.
Avec la feature active, l'orientation de la surface vient seulement des dimensions disponibles : largeur > hauteur donne horizontal ; sinon vertical, carré compris. Aucune résolution exacte n'est exigée. Le parent réduit et centre le cadre complet dans la sortie avec un seul zoom visuel. Cela fonctionne dès le lancement, sans rouvrir les préférences, et lors des redimensionnements sans redémarrer l'app.
Lire les dimensions, réagir si nécessaire
kapp.overlay.layout est disponible dès le démarrage :
format:"16:9"ou"9:16", format réellement utilisé par cette iframe ;width,height: dimensions logiques de l'iframe, en pixels CSS ;viewportWidth,viewportHeight: dimensions disponibles dans la page parent ;scale: zoom visuel déjà appliqué par le parent ;reference: cadre logique du format, utile aux placements enregistrés.
js
const updateLayout = (layout) => {
document.body.dataset.format = layout.format;
// Adapter ici uniquement ce qui est propre à cette app.
};
updateLayout(kapp.overlay.layout);
kapp.overlay.events.on(kapp.overlay.EVENTS.LAYOUT_CHANGED, updateLayout);
// Au nettoyage : events.off(kapp.overlay.EVENTS.LAYOUT_CHANGED, updateLayout).L'événement arrive après la mise à jour du cadre, sans redémarrer l'app. CSS responsive, événement natif resize, ResizeObserver ou dimensions du conteneur conviennent aussi. Un redimensionnement ne doit pas rejouer un paiement, un trigger ou une partie. Sans contexte transmis par le parent, le SDK conserve le cadre horizontal historique.
Placer le contenu de l'app depuis ses préférences
Si le streamer doit déplacer un jeu ou un panneau, exposez une préférence containerArea dans le dashboard de l'app. Sa valeur par défaut et ses contraintes décrivent la zone du contenu. Par exemple, un flipper de 520 × 540 peut rester dans cette zone au sein de l'iframe plein cadre. Le formulaire conserve les placements ; l'app doit les appliquer à son conteneur interne :
js
// La préférence "placement" est déclarée comme containerArea par l'app.
const content = document.querySelector('#game');
const placeContent = () => {
const rect = kapp.overlay.resolveArea(kapp.preferences.get('placement'));
Object.assign(content.style, {
position: 'absolute',
left: `${rect.x}px`, top: `${rect.y}px`,
width: `${rect.w}px`, height: `${rect.h}px`
});
};
placeContent();
kapp.overlay.events.on(kapp.overlay.EVENTS.LAYOUT_CHANGED, placeContent);
// Au nettoyage : events.off(kapp.overlay.EVENTS.LAYOUT_CHANGED, placeContent).La préférence n'est pas un placement automatique de l'iframe. L'app reste libre d'utiliser du CSS responsive, plusieurs conteneurs ou sa propre logique. Les tailles et limites du contenu appartiennent à l'app et à la configuration de ce champ, pas à infos.json.
Médias et rectangles enregistrés
Les inputs mediaFile, containerArea, containerAreas conservent les coordonnées horizontales et ajoutent une variante facultative :
js
const area = {
x: 100, y: 200, w: 640, h: 360,
portrait: {x: 40, y: 300, w: 1000, h: 600}
};
const current = kapp.overlay.resolveArea(area); // {x,y,w,h} dans le cadre courantL'horizontal reste indépendant du vertical. Sans variante, le placement horizontal est réduit proportionnellement et centré. portrait: null revient à ce placement hérité. Une écriture horizontale qui omet portrait conserve la variante enregistrée. Le fichier, le volume et les bornes de lecture restent communs. Les rectangles sont libres, sauf contraintes explicites de l'app.
kapp.medias.playMedia(prefs.monMedia) et KMedia sélectionnent le bon placement et le suivent pendant la lecture. Un changement de format déplace l'image/vidéo existante sans la relancer. Les préférences conservent toujours les deux rectangles : ne remplacez pas la valeur sauvegardée par le résultat de resolveArea.
Les coordonnées passées explicitement à une option de lecture, à playImage, playVideo ou à setPosition sont déjà dans le cadre courant. Elles ne sont pas converties comme une préférence enregistrée. Les lecteurs directs sans coordonnées occupent le cadre courant. Pour un rectangle personnalisé, utilisez resolveArea puis actualisez votre élément lors du changement de layout. Ne multipliez pas ces coordonnées par scale.
Les widgets V2 n'ont aucune déclaration de formats : leur iframe suit les proportions de la surface. Ses dimensions logiques valent les dimensions disponibles divisées par le zoom commun. Leur code peut être responsive ; leurs médias gérés par le SDK suivent automatiquement les placements. Aucune migration des widgets, de leur HTML/CSS/JS ou de leur base de données n'est nécessaire. Le flowchart reste hors périmètre.
Choisir une présentation adaptée à l'app
Examinez les tailles fixes, les coordonnées calculées sur 1920/1080, les zooms CSS/canvas existants, les éditeurs de placement personnalisés, les caméras et les terrains de jeu. Choisissez librement une disposition pertinente : réorganisation, zones différentes, caméra adaptée ou conservation d'un terrain horizontal dans une interface verticale. Une simple permutation largeur/hauteur ne convient pas à tous les jeux. Préservez le fonctionnement horizontal et les préférences existantes.
Recette obligatoire avant publication
Avec le DEV HUB, obtenez la vraie page via prepare_preview (surface overlay, puis external si l'app est interactive). Testez 1920 × 1080, 1280 × 720, 1080 × 1920 et 720 × 1280, puis une surface carrée et une taille intermédiaire. Une app à format unique doit aussi rester dans son format sur une sortie d'une autre orientation. Redimensionnez sans recharger : état de partie, actions, vidéo et son doivent continuer. Vérifiez les interactions, les placements hérités/personnalisés et l'absence de double zoom. Publiez l'app adaptée seulement après la release de la plateforme et la validation de tous ses formats déclarés.