Skip to content

Instantly share code, notes, and snippets.

@Sphinxxxx
Last active March 13, 2024 15:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Sphinxxxx/deaf8572842c3d307bd41b423134fe8d to your computer and use it in GitHub Desktop.
Save Sphinxxxx/deaf8572842c3d307bd41b423134fe8d to your computer and use it in GitHub Desktop.
Image Comparison Slider

Image Comparison Slider

A simple and clean image comparison slider, fully responsive and touch ready made with css and jquery.

A Pen by Andreas Borgen on CodePen.

License.

<h1>Image Comparison Slider</h1>
<h3> Compare images and any html content</h3>
<div class="comparison-container">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/751678/marioPhoto-2.jpg" alt="marioPhoto 2" />
<div class="caption">And I am the <strong>after</strong> image.</div>
<div class="comparison-lhs">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/751678/marioPhoto-1.jpg" alt="marioPhoto 1" />
<div class="caption">I am the <strong>before</strong> image.</div>
</div>
</div>
<h3> Compare more than two images</h3>
<div class="comparison-container">
<img src="https://programming.enthuses.me/assets/codepen/sin-city/scene-comp-3.jpg" alt="" />
<img class="comparison-lhs" data-comparison-splitter="80%" src="https://programming.enthuses.me/assets/codepen/sin-city/scene-comp-2.jpg" alt="" />
<img class="comparison-lhs" data-comparison-splitter="60%" src="https://programming.enthuses.me/assets/codepen/sin-city/scene-comp-1.jpg" alt="" />
</div>
(function() {
"use strict";
function $$(selector) {
return Array.from(document.querySelectorAll(selector));
}
function syncSize(master, slave) {
slave.style.width = master.clientWidth + 'px';
}
function getMouseX(parent, e) {
const bounds = parent.getBoundingClientRect(),
x = e.clientX - bounds.left;
return { x, width: bounds.width };
}
function initComparer(lhs) {
const container = lhs.closest('.comparison-container'),
splitPos = lhs.dataset.comparisonSplitter;
let dragOffset;
//Lock the compared element's width to the original width:
window.addEventListener('load', e => syncSize(container, lhs));
window.addEventListener('resize', e => syncSize(container, lhs));
syncSize(container, lhs);
//Put the compared element into a resizable wrapper:
const lhsWrapper = container.appendChild(document.createElement('div'));
lhsWrapper.classList.add('comparison-lhs-wrapper');
lhsWrapper.appendChild(lhs);
const dragger = container.appendChild(document.createElement('div'));
dragger.classList.add('comparison-dragger');
if(splitPos) {
lhsWrapper.style.width = dragger.style.left = splitPos;
}
//Dragging magic:
dragger.onmousedown = (e) => {
e.preventDefault();
dragOffset = getMouseX(dragger, e);
//console.log(lhs, dragOffset)
};
container.addEventListener('mousemove', e => {
if(dragOffset) {
if(e.buttons === 1) {
e.preventDefault();
const newX = getMouseX(container, e),
relX = (newX.x - dragOffset.x) / newX.width;
lhsWrapper.style.width = dragger.style.left = (Math.max(0, Math.min(relX, 1)) * 100) + '%';
}
else {
dragOffset = undefined;
}
}
});
}
function init() {
$$('.comparison-lhs').forEach(initComparer);
}
init();
})();
.comparison {
&-container {
position: relative;
//Make sure the container doesn't stretch horizontally beyond its content:
display: table;
overflow: hidden;
}
&-lhs, &-lhs-wrapper {
position: absolute;
top:0; left:0;
}
&-lhs {
//For inline elements, such as <img>
display: block;
max-width: none;
}
&-lhs-wrapper {
height: 100%;
width: 50%;
overflow: hidden;
}
&-dragger {
position: absolute;
top:0; left:50%;
width: 0;
height: 100%;
cursor: ew-resize;
&::before {
content: '';
display: block;
width: .4em;
height: 100%;
margin-left: -.2em;
background: rgba(white, .3);
}
&::after {
$button-size: 2.2em;
content: '◀ ▶';
display: block;
position: absolute;
top: 50%; left: 50%;
width: $button-size;
height: $button-size;
margin: $button-size/-2;
border-radius: 100%;
background: white;
text-align: center;
line-height: $button-size;
white-space: nowrap;
}
}
}
/* Page layout - not important */
body {
font-family: Georgia, sans-serif;
//Weird scrollbar flickering in Chrome when the page content exactly fills the page:
overflow-y: scroll;
}
img {
display: block;
width: 100%;
}
.caption {
display: inline-block;
position: absolute;
bottom: .5em; right: .5em;
padding: .5em;
background: rgba(white, .7);
}
.comparison-container {
//width: 100%;
max-width: 1000px;
margin: auto;
}
.comparison-lhs .caption {
right: auto; left: .5em;
}
@ahmed-musallam
Copy link

FYI, this code does not require jQuery, you can change your init method to:

function init() {
    Array.prototype.forEach.call(document.querySelectorAll('.comparison-lhs'), function(el, i){
        initComparer(el)
    });
}

@diefada4545
Copy link

Nice code, but didn't work on movil

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment