Qu'est-ce que c'est, à quoi ça sert ?

Avant|Après est une fonction de comparaison entre deux images. J'ai initialement développé cet outil pour permettre à mes lecteurs de pouvoir très rapidement et avec une grande efficacité, comparer mes photographies avant et après leur traitement. Cela me permet d'accompagner débutants et amateurs dans une logique d'apprentissage ouverte de la photographie. Cette volonté est encore peu répandue, elle est surtout à l'opposé des méthodes puériles que tant de « photographes » adoptent encore, laissant croire — aux plus novices et/ou naïfs — que leurs photos sont « brutes de boîtier », non retouchées, etc. Une tentative d'auto-préservation, bien ridicule, mais surtout trop humaine…
La fonction est particulièrement simple à utiliser : il suffit de placer le curseur de la souris (ou de poser le doigt pour tablettes et smartphones) sur l'image à comparer et la fonction s'active aussitôt, permettant ainsi de comparer deux états différents.

Petit mais costaud

  • Gratuit.
  • Outil simple, efficace et ludique.
  • Comparez ce que bon vous semble.
  • Pour projets perso. ou pro.
  • Multi plate-forme.
  • Tablettes et smartphones.
  • Nombreuses options.
  • Documentation complète.
  • Personnalisez chaque comparaison.
  • Adaptez le code à vos besoins.

Licence

« Avant|Après • Fonction de comparaison »
de Édouard Puginier est mis à disposition selon les termes de la licence Creative Commons Paternité - Partage à l'Identique 3.0 non transposé. Les autorisations au-delà du champ de cette licence peuvent être obtenues à http://tazintosh.com/contact/

Licence Creative Commons

Démonstration et idées

Tout ce qui répond par l'image au concept Avant|Après peut être illustré avec cet outil. Les exemples ci-contre ne sont représentatifs que d'une infime partie du potentiel de la fonction.
Cela ne dépend que de vous !

  • Avant|Après traitement photo
  • Avant|Après amusant ou décalé
  • Avant|Après compositing 3D
  • Avant|Après colorisation
  • Avant|Après maquillage
  • Avant|Après expérience labo.
  • Avant|Après culinaire
  • Avant|Après coiffure
  • Avant|Après nettoyage
  • etc.

Chaque exemple a des réglages spécifiques afin d'illustrer les différentes options de l'outil. Consultez le code au dessous de chacun d'entre eux et découvrez ces différences.

Quoi de neuf dans la dernière version ?

Version 1.5.1 - 30/09/2014

  • Ajout d'un attribut CSS pour éviter le possible débordement de la « poignée ».

Version 1.5 - 26/08/2014

  • Gestion tactile. L'outil fonctionne désormais sur tablettes et smartphones.
  • Option d'affichage d'une « poignée » pour inciter à la manipulation.
  • Option pour la taille de la poignée.
  • Option d'affichage d'une ligne de séparation entre les deux visuels à comparer.
  • Option du positionnement par défaut de la ligne de séparation.
  • Option pour utiliser la comparaison verticalement ou horizontalement.
  • Option pour conserver la comparaison en place même lorsque le doigt ou le curseur quittent la zone.
  • Les classes CSS ont été préfixées pour éviter tout problème de compatibilité. Il vous fraudra mettre à jour vos comparaisons, navré, mais c'est pour la bonne cause ;)
  • Option pour afficher ou non les labels « Avant », « Après ».
  • Option pour personnaliser les labels.
  • Option pour garder les labels tout le temps visibles ou seuleument lors de la comparaison.
  • Chaque option peut être appliquée indépendamment, par comparaison.

Version 1.0 - 25/04/2012

  • Mise à disposition initiale de la fonction de comparaison Avant|Après.

Installation en trois étapes

L'outil se décompose comme suit : le code HTML basiquement constitué des deux images à comparer, incluses dans un conteneur ; une feuille de style CSS ; le code javascript (jQuery) pour gérer l'interaction utilisateur.

#1 HTML

Une comparaison entre deux images est constituée de quatre lignes. Il est possible d'intégrer autant de comparaisons que souhaité dans une page. Par défaut, toutes seront affichées avec les options déclarées dans le Javascript (lignes 10 à 19) ; cependant, elles peuvent indépendamment être paramétrées avec des options différentes (cf. exemples ci-dessus).

<div class="_BA_comparisonArea" style="max-width:630px">
	<img class="_BA_afterElement" src="pathToTheAfterPicture" alt="">
	<img class="_BA_beforeElement" src="pathToTheBeforePicture" alt="">
</div>
<div class="_BA_comparisonArea" style="max-width:630px" data-showhandle="false" data-initialslicepos="50">
	<img class="_BA_afterElement" src="pathToTheAfterPicture" alt="">
	<img class="_BA_beforeElement" src="pathToTheBeforePicture" alt="">
</div>

#2 CSS

La feuille de styles donne l'aspect visuel aux comparaisons et en assure aussi le bon fonctionnement. Elle s'applique à la totalité des comparaisons affichées. Si vous êtes à l'aise avec les CSS, vous pouvez modifier cette feuille de styles selon vos besoins (notamment pour adapter les couleurs à la charte de votre site).
La CSS doit être intégrée dans l'entête <head> de votre site. Une méthode est de copier/coller le code suivant dans un fichier _BA_styles.css que vous appellerez dans l'entête comme suit : <link rel="stylesheet" href="cheminVersLeFichier/_BA_styles.css">.

._BA_comparisonArea {
	cursor: ew-resize;
	position: relative;
	overflow: hidden;
}
._BA_comparisonArea.hasHorizontalSlice {
	cursor: ns-resize;
}

._BA_afterElement,
._BA_beforeElement {
	display: block;
	margin-left: auto;
	margin-right: auto;
	left: 0;
	right: 0;
	top: 0;
}

._BA_beforeElement {
	position: absolute !important;
}

._BA_slice {
	position: absolute;
	width: 1px;
	height: 100%;
	top: 0;
	left: auto;
	background-color: rgba(0, 0, 0, 0.3);
}
._BA_comparisonArea.hasHorizontalSlice ._BA_slice {
	width: 100%;
	height: 1px;
	top: auto;
	left: 0;
}

._BA_handle {
	position: absolute;
	background-color: yellow;
	box-shadow: 0 0 2px rgba(0, 0, 0, 0.4);
}

._BA_label {
	position: absolute;
	font-family: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
	font-weight: bold;
	font-size: 9px;
	line-height: 12px;
	letter-spacing: 1px;
	top: 48%;
	padding: 4px;
	border-radius: 4px;
	color: white;
	background-color: rgba(0, 0, 0, 0.5);
}
._BA_comparisonArea.hasHorizontalSlice ._BA_label {
	margin-left: auto;
	margin-right: auto;
}
._BA_label-left {
	left: 10px;
}
._BA_comparisonArea.hasHorizontalSlice ._BA_label-left {
	top: auto;
	bottom: 10px;
}
._BA_label-right {
	right: 10px;
}
._BA_comparisonArea.hasHorizontalSlice ._BA_label-right {
	top: 10px;
}

#3 Javascript

Le script doit être intégré dans l'entête <head> de votre site. Une méthode est de copier/coller le code suivant dans un fichier _BA_scripts.js que vous appellerez dans l'entête comme suit après l'appel de la librairie jQuery : <script src="cheminVersLeFichier/_BA_scripts.js"></script>.

/* ==================================================================================== */
/* Before|After • Comparison Feature v1.5.1 — © Édouard Puginier — https://tazintosh.com */
/* Under Creative Common license Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)     */
/* ==================================================================================== */

function setupComparison(comparisonArea, reset){
	jQuery(function($){

		/* ========================= Defaults */
		var showHandle = true, // false
			handleSize = 30, // Diameter in px
			showSlice = true, // false
			initialSlicePos = 20, // Percent
			horizontalSlice = false, // true for top to bottom comparison
			keepInPlace = true, // false. Will make “after” image 100% visible when leaving the comparison area
			showLabels = true, // false
			labelBefore = 'AVANT', // Desired label for the before image
			labelAfter = 'APRÈS', // Desired label for the after image
			alwaysShowLabels = false; // Will show labels even while not hover

		/* ========================= Init */
		var pointer = '',
			posX = 0,
			posY = 0,
			slice = null,
			handle = null,
			labels = null,
			offset = '',
			beforeElement = $(comparisonArea).find('._BA_beforeElement'),
			elementWidth = $(beforeElement).width(),
			elementHeight = $(beforeElement).height();

		if (reset){
			$(comparisonArea).removeClass('hasOverlay');
			$(comparisonArea).find('._BA_slice').remove();
			$(comparisonArea).find('._BA_handle').remove();
			$(comparisonArea).find('._BA_label').remove();
		}

		/* ========================= Get values */
		showHandle = ($(comparisonArea).attr('data-showhandle')) ? $(comparisonArea).data('showhandle') : showHandle;
		handleSize = ($(comparisonArea).attr('data-handlesize')) ? $(comparisonArea).data('handlesize') : handleSize;
		showSlice = ($(comparisonArea).attr('data-showslice')) ? $(comparisonArea).data('showslice') : showSlice;
		initialSlicePos = ($(comparisonArea).attr('data-initialslicepos')) ? $(comparisonArea).data('initialslicepos') : initialSlicePos;
		horizontalSlice = ($(comparisonArea).attr('data-horizontalslice')) ? $(comparisonArea).data('horizontalslice') : horizontalSlice;
		keepInPlace = ($(comparisonArea).attr('data-keepinplace')) ? $(comparisonArea).data('keepinplace') : keepInPlace;
		showLabels = ($(comparisonArea).attr('data-showlabels')) ? $(comparisonArea).data('showlabels') : showLabels;
		labelBefore = ($(comparisonArea).attr('data-labelbefore')) ? $(comparisonArea).data('labelbefore') : labelBefore;
		labelAfter = ($(comparisonArea).attr('data-labelafter')) ? $(comparisonArea).data('labelafter') : labelAfter;
		alwaysShowLabels = ($(comparisonArea).attr('data-alwaysshowlabels')) ? $(comparisonArea).data('alwaysshowlabels') : alwaysShowLabels;

		function getEvent(event){
			return event.originalEvent.targetTouches ? event.originalEvent.targetTouches[0] : event;
		}

		/* ========================= Allows to append only once */
		if (!$(comparisonArea).hasClass('hasOverlay')){
			if (showSlice){
				beforeElement.parent().append('<div class="_BA_slice"></div>');
				slice = $(comparisonArea).find('._BA_slice');
			}
			if (showHandle){
				beforeElement.parent().append('<div class="_BA_handle"></div>');
				handle = $(comparisonArea).find('._BA_handle');
			}
			if (showLabels){
				beforeElement.parent().append('<div class="_BA_label _BA_label-left"></div><div class="_BA_label _BA_label-right"></div>');
				labels = $(comparisonArea).find('._BA_label');
			}
		}

		if (showSlice || showHandle || showLabels){ $(comparisonArea).addClass('hasOverlay'); }
		if (horizontalSlice){ $(comparisonArea).addClass('hasHorizontalSlice'); }

		/* ========================= Slice display */
		if ((showSlice) && (slice !== null)){
			if (initialSlicePos === 0){ slice.css('display', 'none'); }
			if (!horizontalSlice){
				posX = elementWidth*initialSlicePos/100;
				slice.css('left', posX + 'px');
			} else {
				posY = elementHeight*initialSlicePos/100;
				slice.css('top', posY + 'px');
			}
		}

		/* ========================= Handle display */
		if ((showHandle) && (handle !== null)){
			handle.css({
				'width': handleSize + 'px',
				'height': handleSize + 'px',
				'border-radius': handleSize + 'px'
			});
			if (!horizontalSlice){
				posY = (elementHeight-handleSize)/2;
				handle.css({
					'margin-left': handleSize / -2 + 'px',
					'top': posY + 'px',
					'left': posX + 'px'
				});
			} else {
				posX = (elementWidth-handleSize)/2;
				handle.css({
					'margin-top': handleSize / -2 + 'px',
					'top': posY + 'px',
					'left': posX + 'px'
				});
			}
		} else {
			if (!horizontalSlice){
				posX = elementWidth*initialSlicePos/100;
			} else {
				posY = elementHeight*initialSlicePos/100;
			}
		}

		/* ========================= Labels display */
		if ((showLabels) && (labels !== null)){
			$(comparisonArea).find('._BA_label-left').html(labelBefore);
			$(comparisonArea).find('._BA_label-right').html(labelAfter);
			if (!alwaysShowLabels) {
				labels.css('display', 'none');
			}
			if (horizontalSlice && showLabels){
				labels.each(function(){
					$(this).css({ // Center labels horizontaly (other attributes are set in the stylesheet)
						'width': $(this).outerWidth(),
						'left': 0,
						'right': 0
					});
				});
			}
		}

		if (!horizontalSlice){
			beforeElement.css('clip', 'rect(auto,' + posX + 'px , auto, auto)');
		} else {
			beforeElement.css('clip', 'rect(' + posY + 'px, auto, auto, auto)');
		}

		/* ========================= Comparison starts */
		$(comparisonArea).on('mouseenter touchstart', function() {
			if (!keepInPlace) {
				if (showSlice){ slice.css('display', 'block'); }
			}
		});

		/* ========================= Comparison is running */
		$(comparisonArea).on('mousemove touchmove', function(event) {
			event.preventDefault();
			pointer = getEvent(event);
			offset = $(this).offset();
			posX = pointer.pageX - (offset.left);
			posY = pointer.pageY - (offset.top);

			if (!horizontalSlice){
				beforeElement.css('clip', 'rect(auto,' + posX + 'px, auto, auto)');
			} else {
				beforeElement.css('clip', 'rect(' + posY + 'px, auto, auto, auto)');
			}
			if ((showSlice) && (slice !== null)){
				if (!horizontalSlice){
					slice.css('left', posX + 'px');
				} else {
					slice.css('top', posY + 'px');
				}
			}
			if ((showHandle) && (handle !== null)){
				handle.css({
					'display': 'none',
					'left': posX + 'px',
					'top': posY + 'px'
				});
			}
			if ((showLabels) && (labels !== null)){ labels.css('display', 'block'); }
		});

		/* ========================= Comparison ends */
		$(comparisonArea).on('mouseleave touchend touchcancel', function() {
			if (!keepInPlace) {
				beforeElement.css('clip', 'rect(auto, 0px, auto, auto)');
				if (showSlice){ slice.css('display', 'none'); }
			} else {
				if (showHandle){ handle.css('display', 'block'); }
			}
			if ((showLabels) && (!alwaysShowLabels)){ labels.css('display', 'none'); }
		});
	});
}

jQuery(function($){
	$(window).load(function(){
		/* ========================= Detecting available comparisons */
		$('._BA_comparisonArea').each(function(){
			setupComparison(this);
		});
	});
});

Ils l'utilisent déjà !

Si vous aussi utilisez cet outil, dites-le moi, parce-que je mettrai alors à jour cette liste avec votre nom, site web et Twitter. Un bon moyen de faire découvrir votre travail !

Stéphane Vilcoq
Photographe
Site web | Facebook
Florian Commaille
Photographe
Site web | @Flo_Commaille
Muriel Auvray
Photographe
Site web | @murielauvray
Sébastien Cour
Photographe
Site web
Julien Tordjman
Photographe
Site web | @neoweb001
TheKeptPromise
Créateur de logiciels
Site web | @TheKeptPromise
Christophe Bailleux
Photographe
Site web | @CBAphoto
Olivier Duval
Photographe
Site web | @oduval
Yannick Lefevre
Photographe
Site web | @Yannick_Lefevre
Grégoire Delatte
Photographe
Site web | @wabgs
Moi ^^
Photographe - CGArtist
Site web | @tazintosh

What else?

Utilisez le formulaire ci-contre ou postez un commentaire pour me soumettre vos avis ou idées de nouvelles options. Si vous apportez des modifications à ce code, merci de les partager en postant un commentaire expliquant le travail réalisé, ou en me contactant via le formulaire. Vous pouvez même joindre un fichier.

De très nombreuses heures de travail on été nécessaires, tant pour développer l'outil que pour le présenter ici. Bien que mis à disposition gratuitement, si vous estimez qu'il rend suffisament service à vos lecteurs ou clients, vous pouvez m'offrir un tikekchose.

This symbolic coffee would be a true expression of your appreciation of this work.

Participez

Taille de téléchargement maximum : 268.44 Mo

Découvrez aussi :