<div class="wrapper">
  <hgroup>
    <h1>CSS Filter Glass</h1>
    <h3>drag an image file from your desktop onto the glass</h3>
  </hgroup>
  <div class="window">
    <div class="glass left img"></div>
    <div class="handle"></div>
    <div class="glass right filter-grayscale img"></div>
  </div>
  <ul class="filter-choice">
    <li data-filter="grayscale">
      <input type="radio" name="filter-choice-group" value="grayscale" class="filter-grayscale img" checked>
    </li>
    <li data-filter="sepia">
      <input type="radio" name="filter-choice-group" value="sepia" class="filter-sepia img">
    </li>
    <li data-filter="blur">
      <input type="radio" name="filter-choice-group" value="blur" class="filter-blur img">
    </li>
    <li data-filter="brightness">
      <input type="radio" name="filter-choice-group" value="brightness" class="filter-brightness img">
    </li>
    <li data-filter="contrast">
      <input type="radio" name="filter-choice-group" value="contrast" class="filter-contrast img">
    </li>
    <li data-filter="hue-rotate">
      <input type="radio" name="filter-choice-group" value="hue-rotate" class="filter-hue-rotate img">
    </li>
    <li data-filter="invert">
      <input type="radio" name="filter-choice-group" value="invert" class="filter-invert img">
    </li>
    <li data-filter="saturate">
      <input type="radio" name="filter-choice-group" value="saturate" class="filter-saturate img">
    </li>
  </ul>
</div>
@import "compass/css3";

$window-width: 800px;
$window-height: $window-width * 9/16; /* keep 16:9 ratio */
$glass-width: $window-width / 2;
$handle-width: 2px;

.wrapper {
  width: 940px;
  margin: 20px auto;
  position: relative;
  color: #fff;
}

/*=== Title ===*/
hgroup {
  text-align: center;
  margin-bottom: 20px;
  
  h1 {
    font-size: 30px;
    margin-bottom: 5px;
    @include text-shadow(0px 1px 3px #999);
  }
  
  h3 {
    font-weight: 300;
  }
}

/*=== Main View ===*/
.window {
  width: $window-width;
  height: $window-height;
  position: relative;
  overflow: hidden;
  float: left;
  margin: 0 20px 20px 70px;
  @include border-radius(5px);
  @include box-shadow(0px 1px 2px 0px #999, inset 0px 1px 1px 0px white);
  
  &.dragover {
    animation: shake 0.5s infinite linear;
  }
}

.glass {
  width: $glass-width;
  height: 100%;
  position: absolute;
  
  &.left {
    left: 0px;
    background-image: none;
    background-size: $window-width;
    background-position: top left;
    @include border-top-left-radius(5px);
    @include border-bottom-left-radius(5px);
  }
  
  &.right {
    right: 0px;
    background-image: none;
    background-size: $window-width;
    background-position: top right;
    margin: -1px;
    padding: 1px;
    @include border-top-right-radius(8px); /* should be 5px, chrome overflow fix */
    @include border-bottom-right-radius(5px);
  }
}

.handle {
  width: $handle-width;
  height: 100%;
  position: absolute;
  background: gray;
  z-index: 1;
  cursor: pointer;
  left: $glass-width - ($handle-width / 2);
  
  &:after {
    content: '‹ ›';
    text-align: center;
    font-family: serif;
    font-size: 24px;
    line-height: 26px;
    display: block;
    position: absolute;
    width: 30px;
    height: 30px;
    border-radius: 100%;
    top: 50%;
    left: 50%;
    margin: -15px 0 0 -15px;
    background: #ddd;
    @include box-shadow(0px 1px 1px 0px #222, inset 0px 1px 1px 0px white);
  }
}

/*=== Filter Menu ===*/
.filter-choice {
  float: left;
  width: 50px;
  height: $window-height;
  position: relative;
  
  > li {
    width: 50px;
    height: 28px;
    margin-bottom: 10px;
    position: relative;
    @include border-radius(5px);
    
    &.alt {
      position: absolute;
      bottom: 0;
      text-align: center;
      
      img:hover {
        background: #999;
        @include border-radius(100%);
        @include box-shadow(0px 0px 1px 0px #999);
      }
    }
    
    &:hover:after {
      content: attr(data-filter);
      display: block;
      position: absolute;
      width: 100px;
      height: 100%;
      line-height: 26px;
      font-size: 12px;
      top: 0;
      left: 115%;
      @include filter(none);
    }
  
    input {
      display: block;
      width: 50px;
      height: 28px;
      cursor: pointer;
      margin: 0;
      background-size: 100%;
      background-repeat: no-repeat;
      @include appearance(none);
      @include border-radius(5px);
      @include transition(box-shadow 0.2s);
      @include box-shadow(0px 1px 2px 0px #999, inset 0px 1px 1px 0px white);
      
      &:hover {
        @include box-shadow(0px 1px 2px 1px #999, inset 0px 1px 1px 0px white);
      }
      
      &:active, &:checked {
        @include box-shadow(inset 0px 1px 3px 1px #999, 0px 1px 1px 0px white);
      }
    }
  }
}

/*=== Filter Classes ===*/
.filter-grayscale {
  @include filter(grayscale(1));
}

.filter-sepia {
  @include filter(sepia(1));
}

.filter-blur {
  @include filter(blur(5px));
}

.filter-brightness {
  @include filter(brightness(0.5));
}

.filter-contrast {
  @include filter(contrast(10));
}

.filter-hue-rotate {
  @include filter(hue-rotate(90deg));
}

.filter-invert {
  @include filter(invert(1));
}

.filter-saturate {
  @include filter(saturate(10));
}

input[type="radio"].filter-blur { /* blur filter fix for thumb */
  @include filter(blur(1px));
}

/*=== Animations ===*/
@keyframes shake {
  0% {
    @include transform(rotate(0deg));
  }
  25% {
    @include transform(rotate(2deg));
  }
  75% {
    @include transform(rotate(-2deg));
  }
  100% {
    @include transform(rotate(0deg));
  }
}

body {
  font-family: 'Open Sans', sans-serif;
  background: #ddd;
  background-image: url(https://cdn.pixabay.com/photo/2018/09/14/22/46/rail-3678287_1280.jpg);
}
var imageWindow = $('.window');
var leftGlass = $('.glass.left');
var rightGlass = $('.glass.right');
var initialWidth = leftGlass.width();

// Drag and Drop event listeners
imageWindow.on('dragover', onDragOver);
imageWindow.on('dragenter', onDragEnter);
imageWindow.on('dragleave', onDragLeave);
imageWindow.on('drop', onDrop);

// Glass handle drag behavior
$('.handle').draggable({axis: 'x',
  containment: 'parent',
  drag: function(event, ui) {
    var handleOffset = ui.position.left - initialWidth;
    
    leftGlass.width(initialWidth + handleOffset);
    rightGlass.width(initialWidth - handleOffset);
  }
});

// Filter chooser events
$('input[name="filter-choice-group"]').on('click', function() {
  // remove any previous filter-* class from right glass
  rightGlass.removeClass(function (index, css) {
    return (css.match (/\bfilter-\S+/g) || []).join(' ');
  });
  
  // add the selected filter class to the right glass
  rightGlass.addClass('filter-' + $(this).val());
});

setImage('https://images.unsplash.com/photo-1544390951-7b9e6547fb28?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80');

function setImage(uri) {
  $('.img').css('background-image', 'url('+uri+')');
}

// Drag And Drop event handlers
function onDragOver(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  evt.originalEvent.dataTransfer.dropEffect = 'copy';
}

function onDragEnter(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  $('.window').addClass('dragover');
}

function onDragLeave(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  $('.window').removeClass('dragover');
}

// Thanks Eric Bidelman :)
function onDrop(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  $('.window').removeClass('dragover');
  
  // Allowed file types
  var allowedFileTypes = /image.*/;
  
  // Get dropped file object
  var file = evt.originalEvent.dataTransfer.files[0];
  
  // Validate allowed type, or break
  if (!file.type.match(allowedFileTypes)) {
    return;
  }
  
  // Setup FileReader
  var reader = new FileReader();
  reader.onerror = function(evt) { 
    console.log('FileReader error: ' + e.target.error); 
  }
  reader.onload = (function(aFile) {
    return function(evt) {
      // Set dropped file as current image
      setImage(evt.target.result);
    }
  })(file);
  
  reader.readAsDataURL(file);
}

External CSS

  1. //ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
  2. //ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js