Skip to content

API de mise à l'échelle et de centrage

comp-hub uniquement

$onScaleChange est injecté par l'environnement d'aperçu de comp-hub. Ce N'EST PAS une API standard du framework et n'existe pas en dehors de comp-hub. Pour les composants Vue, il est ajouté à l'instance Vue (this.$onScaleChange), et pour les composants React, il est passé comme prop onScaleChange. Si vous utilisez cette API dans votre composant, assurez-vous de la protéger contre undefined lors de l'exécution en dehors de comp-hub.

$onScaleChange s'abonne aux changements de taille du conteneur et calcule automatiquement les styles de mise à l'échelle et de centrage, aidant le contenu à s'adapter au conteneur d'aperçu.

Pourquoi la mise à l'échelle ?

Le panneau d'aperçu miniature dispose d'un espace limité (généralement environ 300×200), mais certains composants affichent un contenu riche (graphiques, tableaux, mises en page de formulaires complexes, etc.). Sans mise à l'échelle, seule une partie de la zone est visible dans le panneau miniature, rendant impossible de voir le composant complet. L'API de mise à l'échelle vous permet de définir une taille de contenu prédéfinie (par exemple, 800×500) et la met automatiquement à l'échelle pour s'adapter au conteneur miniature, gardant tout visible.

ts
type ScaleMode = "widthFirst" | "heightFirst" | "contain" | "cover"

interface ScaleStyle {
  transform: string       // e.g. "translate(100px, 50px) scale(0.75)"
  transformOrigin: string // always "left top"
}

Modes de mise à l'échelle

ModeComportement
"widthFirst"Mise à l'échelle pour s'adapter à la largeur du conteneur, la hauteur peut déborder
"heightFirst"Mise à l'échelle pour s'adapter à la hauteur du conteneur, la largeur peut déborder
"contain"Mise à l'échelle proportionnelle, contenu entièrement visible dans le conteneur (défaut recommandé)
"cover"Mise à l'échelle proportionnelle, contenu remplit le conteneur (peut rogner l'excédent)

Tous les modes centrent le contenu à l'intérieur du conteneur via translate.

$onScaleChange(params, callback) → désabonnement

S'abonne aux changements de taille du conteneur. Le callback est invoqué immédiatement avec la mise à l'échelle actuelle, puis à nouveau à chaque redimensionnement du conteneur.

ts
const unsubscribe = this.$onScaleChange(
  params: { mode: ScaleMode, width: number, height: number },
  callback: (style: ScaleStyle) => void
): () => void

Utilisation (React)

La version React de l'API de mise à l'échelle est passée comme prop onScaleChange à votre composant de démo :

jsx
import React, { useEffect, useState } from "react";

const DemoMini = ({ onScaleChange }) => {
  const [scaleStyle, setScaleStyle] = useState({});

  useEffect(() => {
    if (onScaleChange) {
      const unsubscribe = onScaleChange(
        { mode: "contain", width: 800, height: 500 },
        (style) => setScaleStyle(style)
      );
      return unsubscribe; // cleanup on unmount
    }
  }, [onScaleChange]);

  return (
    <div style={scaleStyle}>
      {/* your content */}
    </div>
  );
};

export default DemoMini;

Utilisation (API Options Vue 2)

vue
<script>
export default {
  data() {
    return { scaleStyle: {} }
  },
  mounted() {
    // S'abonner — recalcule automatiquement lors du redimensionnement du conteneur
    this._unsub = this.$onScaleChange(
      { mode: "contain", width: 800, height: 500 },
      (style) => { this.scaleStyle = style }
    )
  },
  beforeDestroy() {
    this._unsub?.() // Nettoyer l'abonnement
  }
}
</script>

Utilisation (API Composition Vue 3)

vue
<script setup>
import { ref, getCurrentInstance, onBeforeUnmount } from "vue"

const instance = getCurrentInstance()
const scaleStyle = ref({})

const unsub = instance.proxy.$onScaleChange(
  { mode: "contain", width: 800, height: 500 },
  (style) => { scaleStyle.value = style }
)

onBeforeUnmount(() => unsub())
</script>

Modèles courants

Composant de démo avec taille de contenu fixe

Les composants de démo d'aperçu déclarent généralement une zone de contenu fixe, puis utilisent l'API de mise à l'échelle pour remplir le panneau d'aperçu :

vue
<template>
  <div class="demo-wrapper" :style="scaleStyle">
    <!-- Contenu conçu pour 800×500 -->
    <div class="demo-content">...</div>
  </div>
</template>

<script>
export default {
  data() {
    return { scaleStyle: {} }
  },
  mounted() {
    this._unsub = this.$onScaleChange(
      { mode: "contain", width: 800, height: 500 },
      (style) => { this.scaleStyle = style }
    )
  },
  beforeDestroy() {
    this._unsub?.()
  }
}
</script>

<style scoped>
.demo-wrapper {
  transform-origin: left top;
}
.demo-content {
  width: 800px;
  height: 500px;
  overflow: hidden;
}
</style>

Bonnes pratiques

  1. Nettoyez les abonnements — appelez toujours unsubscribe() dans beforeDestroy / onBeforeUnmount pour éviter les fuites de mémoire
  2. Taille de contenu fixe — concevez votre démo avec une largeur × hauteur spécifique (par exemple, 800×500) et laissez l'API de mise à l'échelle gérer le reste
  3. contain est le défaut sûr — il garantit que tout le contenu est visible même dans les petits panneaux
  4. Protégez pour les environnements non-comp-hub — puisque cette API n'existe que dans l'aperçu comp-hub, vérifiez toujours sa disponibilité avant d'appeler :
js
// Modèle d'appel sûr
if (this.$onScaleChange) {
  this._unsub = this.$onScaleChange(
    { mode: "contain", width: 800, height: 500 },
    (style) => { this.scaleStyle = style }
  )
}

Les composants téléversés par les utilisateurs sont open source