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...