JSFiddle - React, Tailwind, and code Playground
by BurpmanJunior
HTML
<div class="main">
<h1>Image<br />Compare.</h1>
<p>Drag left and right to compare before and after.</p>
<img
src="https://i.imgur.com/gAgfUDk.jpg"
data-imagecompare="https://i.imgur.com/JsMd7Gp.jpg"
alt="Comparison #1"
/>
<img
src="http://i.imgur.com/xI4FBHa.jpg"
data-imagecompare="http://i.imgur.com/Mao9xQ9.jpg"
alt="Comparison #2"
/>
<img
src="http://i.imgur.com/uLxLty5.jpg"
data-imagecompare="http://i.imgur.com/UAi1vr3.jpg"
data-imagecomparestart="0.95"
alt="Comparison #3"
/>
<p>Images via <a href="https://unsplash.com/" target="_blank">Unsplash</a></p>
</div>
SCSS
//-------------------//
//-- Image Compare --//
//-------------------//
.image-compare{
-webkit-tap-highlight-color: rgba(#fff, 0);
display : block;
font-size : 16px;
margin : 0 auto;
overflow : hidden;
padding : 0;
position : relative;
user-select : none;
// Box sizing resets
&,
& *,
& *:before,
& *:after{
box-sizing: border-box;
}
// Image resets
img{
display: block;
width : 100%;
}
//-- Comparison wraps --//
figure{
display : block;
margin : 0 auto;
overflow: hidden;
padding : 0;
position: relative;
&.image-compare-before{
img{
margin: 0 0 0 auto;
}
}
&.image-compare-after,
&.image-compare-after img{
bottom : 0;
position : absolute;
top : 0;
transform-origin: 0 0;
width : 100%;
&.image-compare-after{
transform: translateX(100%);
}
&.image-compare-after img{
transform: translateX(-100%);
}
}
}
//-- UI --//
.image-compare-handle{
bottom : 0;
cursor : pointer;
display : block;
left : 0;
position : absolute;
top : 0;
transform : translateX(50%);
transform-origin: 0 0;
transition : opacity 300ms;// transform 60ms;
width : 200%;
//-- UI - Line --//
&:before{
background-color: #fff;
bottom : 0;
box-shadow : 0 0 1em rgba(#000, 0.5);
content : '';
cursor : col-resize;
display : block;
left : 50%;
position : absolute;
top : 0;
transform : translateX(-50%) scaleY(0);
transform-origin: center;
transition : transform 300ms;
width ...
Babel + JSX
/**
* Creates image comparison using image src as before and data-imagecompare as after
* @param {object} image Image DOM element
* @return {object} Self
*/
let imageCompare = function(image){
console.log(image);
// Validate inputs
if(!image.getAttribute(`data-imagecompare`) || !image.src){ return false; }
// UI horizontal translation ranges
this.ranges = {
after: [0, 100], // After image wrap
after_img: [0, -100], // After image inner
handle: [-50, 0] // UI control
};
// Get image URL references
this.images = {
before: image.src,
after: image.getAttribute(`data-imagecompare`)
};
// Animation variables
this.intro_duration = 500;
this.transition_duration = 150;
this.transition_clear = null;
this.transition_state = false;
this.transition_ignore = false;
this.start_factor = 0.95;
// Get initial factor if available
let start_factor = image.getAttribute(`data-imagecomparestart`);
if(start_factor){
start_factor *= 1;
this.start_factor = (start_factor >= 0 && start_factor <= 1 ? start_factor : this.start_factor);
}
// After image preload
let preload = new Image();
preload.src = this.images.after;
preload.onload = () => {
// Init imageCompare
this.initDom(image);
};
return this;
};
/**
* Initializes control DOM and sets up opening animation
* @param {object} image Image element
*/
imageCompare.prototype.initDom = function(image){
// Get available alt text for screen readers
let alt_text = image.getAttribute(`alt`) || null;
// Create main comparison wrap
this.wrap = document.createElement(`div`);
this.wrap.className = `image-compare`;
// Append wrap
this.wrap = image.parentElement.insertBefore(this.wrap, image.nextSibling);
image.parentElement.removeChild(image);
// Create "before" wrap and image elements
this.before = document.createElement(`figure`);
this.before.className...