Mise en œuvre d’une fonction de zoom interactif sur images dans les applications rapides

Pour offrir une expérience visuelle enrichie dans les applications rapides (Quick Apps), il est possible de simuler un effet de zoom localisé sur une image sans recourir à des composants natifs dédiés. Cette approche repose sur la combinaison dynamique de propriétés CSS — notamment background-image, background-size et background-position — couplée à la gestion précise des événements tactiles.

Principe technique

L’effet de zoom est obtenu en affichant l’image source comme arrière-plan d’un conteneur fixe, puis en ajustant sa taille (background-size) pour agrandir le contenu, tout en déplaçant visuellement la zone visible via background-position. La position cible du zoom est calculée en temps réel à partir des coordonnées tactiles relatives à l’élément image.

Gestion des coordonnées tactiles

Lors d’un glissement sur l’image, l’événement ontouchmove fournit les décalages offsetX et offsetY. Ces valeurs sont inversées et limitées aux dimensions du conteneur afin d’éviter les débordements. Le code suivant illustre une version refactorisée avec une logique plus robuste et des noms de variables explicites :

handleTouchMove(event) {
  this.isZoomActive = true;
  const touch = event.changedTouches[0];
  const { offsetX, offsetY } = touch;

  // Contraintes de déplacement : maintenir la vue dans les limites
  const maxX = this.containerWidth - this.zoomedWidth;
  const maxY = this.containerHeight - this.zoomedHeight;

  this.backgroundOffsetX = Math.max(maxX, Math.min(0, -offsetX));
  this.backgroundOffsetY = Math.max(maxY, Math.min(0, -offsetY));
}

Structure HTML et styles

Le rendu repose sur deux éléments distincts : un <image> déclenchant les interactions, et un <div> servant de fenêtre de zoom. Ce dernier utilise un fond personnalisé dont les propriétés évoluent dynamiquement :

<template>
  <div class="app-root">
    <text class="header">Zoom tactile sur image</text>
    <image 
      class="source-image" 
      src="/assets/photo.jpg" 
      ontouchmove="handleTouchMove" 
      ontouchend="handleTouchEnd"
    />
    <div 
      class="zoom-view" 
      show="{{isZoomActive}}" 
      style="background-position: {{backgroundOffsetX}}px {{backgroundOffsetY}}px;"
    ></div>
  </div>
</template>

<style>
.app-root { flex-direction: column; align-items: center; padding: 20px; }
.header { font-size: 48px; margin-bottom: 30px; }
.source-image { width: 500px; height: 500px; }
.zoom-view {
  width: 500px;
  height: 500px;
  background-image: url(/assets/photo.jpg);
  background-size: 1000px 1000px;
  background-repeat: no-repeat;
  margin-top: 20px;
  border: 2px solid #007DFF;
}
</style>

<script>
module.exports = {
  data: {
    isZoomActive: false,
    backgroundOffsetX: 0,
    backgroundOffsetY: 0,
    containerWidth: 500,
    containerHeight: 500,
    zoomedWidth: 1000,
    zoomedHeight: 1000
  },
  handleTouchMove(event) {
    this.isZoomActive = true;
    const touch = event.changedTouches[0];
    const { offsetX, offsetY } = touch;

    const maxX = this.containerWidth - this.zoomedWidth;
    const maxY = this.containerHeight - this.zoomedHeight;

    this.backgroundOffsetX = Math.max(maxX, Math.min(0, -offsetX));
    this.backgroundOffsetY = Math.max(maxY, Math.min(0, -offsetY));
  },
  handleTouchEnd() {
    this.isZoomActive = false;
  }
};
</script>

Cette implémentation garantit un contrôle fluide du point de zoom, avec des limites naturelles empêchant le déplacement hors cadre. Le facteur d’agrandissement est enttièrement configurbale via background-size, permettant d’ajuster la résolution apparente selon les besoins.

Étiquettes: quickapp css-background zoom-interaction

Publié le 11 octobre à 07h43