What is it, what's for?

Before|After is a comparison feature between two images. I originally developed this tool to allow my readers to be able to very quickly and with high efficiency, compare my photographies before and after the post-processing. This allows me to support beginners and amateurs in a logic of learning photography in an opened way. This habit is still uncommon, it is especially in contrast to nauseous methods so many people still adopt, suggesting — to the most novice and/or naive — that their photos are unedited, right from the camera, etc. A pseudo attempt at self-preservation, very ridiculous, but also human too…
The function is particularly simple to use: just place the mouse cursor over the image to be compared and the function is activated immediately, thus allowing, while you ride the cursor, to compare two different states.

Small but powerful

[taz_embeddedcolumn width="50"]
  • Free.
  • Easy tool, efficient and fun.
  • Compare just anything you want.
  • For personal & pro. projects
  • Cross-platform.
[/taz_embeddedcolumn] [taz_embeddedcolumn width="50"]
  • Tablets and Smartphones.
  • Many options.
  • Complete documentation.
  • Customize each comparison.
  • Adapt the code to your needs.
[/taz_embeddedcolumn]

License

“Before|After • Comparison Feature”
by Édouard Puginier is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. Permissions beyond the scope of this license may be available at http://tazintosh.com/en/contact/

Creative Commons License

Demos and ideas

Everything that can answer to the concept of Before|After fits this tools. Examples below against are only a minimal part of the feature potential.
It's just up to you!

  • Before|After photo adjustments
  • Before|After funny
  • Before|After 3D Compositing
  • Before|After Colorization
  • Before|After Make-Up
  • Before|After laboratory experiment
  • Before|After culinary
  • Before|After hairdressing
  • Before|After cleaning-up
  • etc.

Each example provided here has specifics settings to demonstrates the tool features. Check-out the code under each to discover them.

What's new on the last version?

Version 1.5.1 - 30/09/2014

  • Added a CSS attribute to avoid a possible overflow of the handle.

Version 1.5 - 26/08/2014

  • Touch events! The tool now works on tablets and smartphones.
  • Option to display a handled to encourage manipulation.
  • Option for the handle size.
  • Option to display a slice line between the two elements to compare.
  • Option to set the default position of the slice.
  • Option for horizontal or vertical comparison.
  • Option to keep the comparison in place even if the mouse or the finger leave the area.
  • CSS Classes have been prefixed to avoid compatibility problem. You'll have to update your existing comparisons, I'm sorry about that, but it's for a good cause ;)
  • Option to display or not labels “Before”, “After”.
  • Option to customize labels.
  • Option to keep labels always visible or only when comparing.
  • Each option can be applyed independently on each comparison.

Version 1.0 - 25/04/2012

  • Initial public release of Before|After comparison feature.

Three steps install

The tool is composed as follows: the HTML code basically constituted of the two images to compare, included in a container; a CSS stylesheet; the Javascript (jQuery) code to handle the user interaction.

#1 HTML

A two images comparison is built upon 4 lines of codes. It's possible to add as many comparison as needed on a page. By default, all of them are displayed with the default options set in the Javascript (lines 10 to 19). However, each comparison can be set independently with specifics options (see above examples).

<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

The stylesheet provides the look to the comparaison and also make them work the good way. It applies to all comparisons on screen. If you know about CSS, you can modify this style to your needs (specialy to adapt colors to your visual identity).
You may add the CSS to the <head> of your website. A method is to copy/paste the following code on a file _BA_styles.css you'll then call on the head like this: <link rel="stylesheet" href="pathToMyFile/_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

The script may be added into the <head> of your website. A method is to copy/paste the following code on a file _BA_scripts.js that you'll call on the head after the jQuery library call, like this: <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 = 'BEFORE', // Desired label for the before image
			labelAfter = 'AFTER', // 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('
'); slice = $(comparisonArea).find('._BA_slice'); } if (showHandle){ beforeElement.parent().append('
'); handle = $(comparisonArea).find('._BA_handle'); } if (showLabels){ beforeElement.parent().append('
'); 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); }); }); });

They are using it!

If you too, are using this tool, let me know and I'll update this list with your name, website and Twitter.
A good way to make your work known!

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

What else?

Use the form following or post a comment at the bottom of this article to share your ideas/needs. If you make changes to the code, thank you for sharing them by posting a comment explaining the work done, or by sending me an email using this form. You can even attach a file.

Many hours have been needed to develop this tool and present it here. Even if it's provided for free, if you think it gives a great service to your readers or customers, you can offer me littl'somethin'.

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

Participate

Drop a file here or click to upload Choose File
Maximum upload size: 268.44MB

Also discover: