Skip to content

Planches d'images et atlas

Une appli qui charge beaucoup de fichiers image déclenche autant de requêtes HTTP. En production, les fichiers propres à l'app peuvent être servis directement par Bunny ; en local, ils viennent du DEV HUB. Regrouper les images dans une ou plusieurs planches réduit les requêtes du navigateur et reste une bonne pratique web dans les deux contextes.

Générer un atlas dans le DEV HUB

Dans la page de l'appli, ouvre l'onglet Assets et utilise Créer un atlas. Choisis le dossier source, le dossier de sortie et le nom de l'atlas, lance d'abord Analyser, puis Créer l'atlas.

Le but principal est de réduire le nombre de requêtes, pas nécessairement le poids total. L'analyse encode réellement les planches en mémoire et affiche les requêtes avant/après, le poids avant/après, le nombre de planches et un avertissement si l'atlas devient plus lourd.

Réglages disponibles :

  • profils UI, Cartes, Sprites pixel-art ou personnalisé ;
  • planches MaxRects de 1024, 2048 ou 4096 px, avec plusieurs planches si nécessaire ;
  • WebP avec pertes et qualité réglable (85 par défaut), ou PNG optimisé pour le pixel-art et les assets qui doivent rester sans perte ;
  • largeur/hauteur maximale facultative pour réduire les images avant placement, sans les agrandir ;
  • découpe des marges transparentes et extrusion de 1 px indépendamment activables.

Le créateur accepte récursivement PNG, JPEG, WebP et GIF statiques. Il refuse les fichiers animés ou corrompus. Le même traitement est disponible pour un agent via le tool MCP create_image_atlas (compact_image_assets reste un alias historique) :

json
{
  "app": "mon-app",
  "source_dir": "assets/images",
  "output_dir": "assets/atlas",
  "atlas_name": "game",
  "profile": "cards",
  "max_size": 4096,
  "format": "webp",
  "webp_quality": 85,
  "trim": false,
  "extrude": true,
  "resize_max_width": 1024,
  "analyze_only": false
}

Les clés de frames sont les chemins relatifs au dossier source, normalisés avec /, extension comprise. Exemple : characters/boss.webp.

Le créateur d'atlas ne supprime jamais les images sources. Une fois le code migré et vérifié, supprime-les toi-même ou ajoute-les aux exclusions de cli-config.json avant le prochain push.

Plugin autonome, sans SDK

Charge le lecteur public versionné, puis l'atlas JSON :

html
<script src="https://kappapps.app/assets/image-atlas/kappapps-image-atlas-1.0.js"></script>
<script>
  (async () => {
    const atlas = await KappappsImageAtlas.load('./assets/atlas/game.json');
    const frame = atlas.get('characters/boss.webp');

    if (frame) {
      document.body.append(await frame.toImage());
    }

    // À appeler quand le plugin n'utilise plus l'atlas.
    // atlas.dispose();
  })();
</script>

La déclaration TypeScript autonome est publiée à /assets/image-atlas/kappapps-image-atlas-1.0.d.ts.

Appli ou widget avec le SDK

Le SDK embarque exactement la même implémentation sous k.ImageAtlas, sans requête de script supplémentaire :

js
const atlas = await k.ImageAtlas.load('./assets/atlas/game.json');
const frame = atlas.get('ui/icons/trophy.png');

if (frame) {
  frame.draw(canvas.getContext('2d'), 20, 20);
  console.log(frame.width, frame.height, frame.trimmed);
}

API publique :

  • await KappappsImageAtlas.load(url) ou await k.ImageAtlas.load(url) charge le manifeste et ses planches ;
  • keys(), has(name) et get(name) donnent accès aux frames ;
  • une frame fournit width, height, trimmed, draw(), toCanvas(), toBlob() et toImage() ;
  • draw() et les exports reconstruisent les marges transparentes supprimées au compactage ;
  • dispose() libère les références détenues par l'atlas et rend l'instance inutilisable.

Les URLs de planches sont résolues relativement au JSON. Les images sont chargées avec CORS activé, ce qui convient aux routes d'assets et aux plugins Kappapps.

Phaser

Le manifeste produit est un multi-atlas compatible avec le loader Phaser :

js
function preload() {
  this.load.multiatlas('game', './assets/atlas/game.json', './assets/atlas/');
}

function create() {
  this.add.image(400, 300, 'game', 'characters/boss.webp');
}

Le troisième argument indique à Phaser le dossier des planches référencées dans le JSON. Le manifeste contient textures[] et les champs TexturePacker attendus par Phaser. Il ajoute aussi des métadonnées Kappapps versionnées et un hash de contenu déterministe.