Comparaison d’image avant/après en javascript

Dernièrement, j’ai eu besoin d’intégrer dans une publication un script permettant de mettre en évidence l’évolution d’un visuel avant et après modification. Pour ce faire, le principe de base a été de superposer deux images dans un élément <div> et d’appliquer un masque paramétrable à l’image qui se trouvait positionnée au dessus via la propriété CSS clip-path. Ensuite, il a fallut répondre aux évènements de click ou de cliquer/glisser dans l’image en positionnant l’extrémité verticale du masque à la nouvelle coordonnée du pointeur sur l’axe horizontal.

1re méthode : les évènements de pointeur

Afin de récupérer les coordonnées du pointeur en javascript, j’ai d’abord pensé faire appel aux évènements de pointeur. De cette façon, j’ai abouti à un script fonctionnel dans lequel il fallait combiner les évènements pointerdown, pointermove et pointerleave afin de parvenir à un résultat satisfaisant et fluide.

See the Pen before-after clip-path image without input range by Jensen SIU (@seanGooGoo) on CodePen.

2nde méthode : l’élément input range

Ce script me paraissait trop compliqué et peut-être un peu expérimental. C’est pourquoi, j’ai cherché s’il n’existait pas de manière plus élégante de parvenir au même résultat et j’ai découvert la proposition de Cagri Kizilkan sur Codepen. Sa proposition consiste à utiliser les propriétés natives de l’élément <input type="range"> en modifiant son style CSS. Ainsi, plus besoin de faire appel aux évènements de pointeur, la valeur du champ input peut directement être récupérée dans le script et le code s’en trouve énormément simplifié.

Sa solution est très ingénieuse mais la difficulté de faire appel à ce contournement réside précisément dans la modification des propriétés de style de l’élément <input type="range"> et j’ai légèrement bataillé avec la feuille de style pour parvenir au résultat que j’attendais.
En effet, il n’est pas simple d’appliquer un style personnalisé au champs de type “range” car il se divise en deux sous éléments : le rail et le poussoir qui possèdent chacun un comportement de style très singulier sous les différents navigateurs et terminaux. Il faut prendre de soin de bien les tester partout pour parvenir à un rendu unifié car on se trouve contraint à l’utilisation de préfixes navigateur pour cela.

Pour en apprendre plus au sujet du style de l’élément input range sur CSS-Tricks : Styling Cross-Browser Compatible Range Inputs with CSS.

Les préfixes navigateur

Les deux préfixes utiles dans ce cas de figure sont ceux de Mozilla et Webkit. En SCSS, j’ai pris l’habitude de grouper les déclarations mais dans ce cas, attention, cela ne fonctionne pas et on peut perdre plusieurs dizaines de minutes à essayer de comprendre pourquoi un code correct ne fonctionne pas. Il faut bien déclarer deux fois les définitions quasiment identiques des propriétés de -moz-range-thumb et de -webkit-slider-thumb.

    input[type="range"] {
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
      position: absolute;
      display: flex;
      overflow: hidden;
      justify-content: center;
      align-items: center;
      height: 100%;        
      width: calc(100% + var(--ba-thumb-size));
      inset: 0;
      margin: 0 calc( 0px - calc(var(--ba-thumb-size) / 2) );
      padding: 0;
      background-color: transparent;
      cursor: pointer;
      &::-webkit-slider-thumb {
        -webkit-appearance: none;
        appearance: none;
        background-color: transparent;
        box-shadow: 0 0 0 transparent;
        width: var(--ba-thumb-size);
        min-height: 100vh;
        border: 0;
        border-radius: 0;
        cursor: col-resize;
     }
      &::-moz-range-thumb {
        -moz-appearance: none;
        appearance: none;
        background-color: transparent;
        box-shadow: 0 0 0 transparent;
        width: var(--ba-thumb-size);
        min-height: 100vh;
        border: 0;
        border-radius: 0;
        cursor: col-resize;
      }
    }

Ailleurs sur le Web

Pendant la rédaction de cet article, j’ai découvert que la société Elfsight propose un widget reprenant le même principe que ce à quoi je me suis appliqué ici. Bien entendu, il offre plus de possibilités et fait parti d’un pack de widgets proposant d’autres fonctionnalités mais j’ai été plutôt surpris que ce genre de script soit proposé à la vente par abonnement. Payer pour cela me semble légèrement abusif! Le code proposé ici est gratuit et il le sera pour toujours!

See the Pen before-after clip-path on image with input range by Jensen SIU (@seanGooGoo) on CodePen.

CodeCSSJavascript

Aucun commentaire

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *