<svg id="gallery" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 800" width="1100" height="800">
  <defs>
    <mask id="masterMask">
      <rect x="50" y="100" width="1000" height="600" fill="#fff" />
      <rect x="50" y="600" width="1000" height="200" fill="#fff" rx="15" ry="15" />
    </mask>
    <mask id="slideMask">
      <rect id="theSquare" x="-950" y="100" width="1000" height="700" fill="#fff" />
    </mask>
    <mask id="captionMask">
      <rect x="50"  y="0" width="1000" height="100" fill="#fff"/>
    </mask>
    <mask id="draggerMask">
      <circle cx="50" cy="450" r="30" fill="#fff"/>
      <circle cx="1050" cy="450" r="30" fill="#fff"/>
      <rect x="50" y="0" width="1000" height="800" fill="#fff" rx="18" ry="18" />
    </mask>
  </defs>
  <title>Before and After Gallery</title>
  <g mask="url(#masterMask)">
    <g class="allPics">
      <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/before00.jpg" x="50" y="100" width="1000" height="700" />
      <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/before01.jpg" x="50" y="800" width="1000" height="700" />
      <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/before02.jpg" x="50" y="1500" width="1000" height="700" />
    </g>
    <g mask="url(#slideMask)">
      <g class="allPics">
        <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/after00.jpg" x="50" y="100" width="1000" height="700" />
        <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/after01.jpg" x="50" y="800" width="1000" height="700" />
        <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/after02.jpg" x="50" y="1500" width="1000" height="700" />
      </g>
    </g>
  </g>
  <g mask="url(#captionMask)">
    <rect x="50"  y="50" width="1000" height="50" fill="#68B3AF"/>
    <rect x="50"  y="0" width="1000" height="100" rx="15" ry="15" fill="#68B3AF"/>
    <g class="allCaptions" fill="white">
      <g class="captions">
        <text transform="translate(80 67.05)" font-size="55" >Kitchen Remodel</text>
        <text transform="translate(561 40.33)" font-size="28" >Contractor: XYZ Kitchen Updates
          <tspan x="0" y="33.6" xml:space="preserve">Budget: $25,000</tspan>
          <tspan x="230.88" y="33.6">Time: 8 weeks</tspan>
        </text>
      </g>
      <g transform="translate(0 100)" class="captions">
        <text transform="translate(80 67.05)" font-size="55" >Basement Bath</text>
        <text transform="translate(561 40.33)" font-size="28" >Contractor: The Bath Dudes
          <tspan x="0" y="33.6" xml:space="preserve">Budget: $11,000</tspan>
          <tspan x="230.88" y="33.6">Time: 4 weeks</tspan>
        </text>
      </g>
      <g transform="translate(0 200)" class="captions" >
        <text transform="translate(70 67.05)" font-size="55" >Hang your clothes</text>
        <text transform="translate(561 40.33)" font-size="28" >Why? Because your mom said so.
          <tspan x="0" y="33.6" xml:space="preserve">Budget: $0</tspan>
          <tspan x="180.88" y="33.6">Time: Immediately!</tspan>
        </text>
      </g>
    </g>
  </g>
  <rect x="52" y="2" width="996" height="796" fill="none" stroke-width="4" stroke="#fff" rx="15" ry="15" />
  <g mask="url(#draggerMask)">
    <g id="dragger">
      <line id="divider" x1="50" y1="100" x2="50" y2="800" fill="none" stroke="#fff" stroke-width="2" stroke-miterlimit="10"/>
      <circle id="draggerBase" cx="50" cy="450" r="30" fill="#68B3AF"/>
      <circle id="outline" cx="50" cy="450" r="26" fill="none" stroke="#fff" stroke-miterlimit="10" stroke-width="2"/>
      <polygon id="leftTriangle" points="67.21 449.62 60.11 453.73 53 457.83 53 449.62 53 441.42 60.11 445.52 67.21 449.62" fill="#fff"/>
      <polygon id="rightTriangle" points="32.79 449.62 39.89 445.52 47 441.42 47 449.62 47 457.83 39.89 453.73 32.79 449.62" fill="#fff"/>
    </g>
  </g>
</svg>
<div class="controls">
  <div class="newPic">Kitchen Remodel</div>
  <div class="newPic">Basement Bathroom</div>
  <div class="newPic">Pick Up Your Clothes</div>
</div>
* {
  box-sizing: border-box;
}

body {
  height: 100vh;
  width: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
  font-family: 'Roboto', sans-serif;
  font-weight: 700;
  display: flex;
  align-content: center;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #655643;
}

#gallery {
  max-width: 100%;
  max-height: 80%;
}

.newPic {
  color: white;
  padding: 5px 20px;
  background-color: #68B3AF;
  border-radius: 25px;
  border: solid 2px #fff;
  height: 50px;
  font-size: 1.1em;
  cursor: pointer;
  margin: 5px 5px 0 5px;
  display: flex;
  align-items: center;
}

.newPic:hover {
  background-color: #518a8c;
}

.controls {
  display: flex;
  flex-wrap: wrap;
  margin: 20px;
  justify-content: center;
}
var $buttons = $(".newPic");
var startY = 0;
var initTimeline = new TimelineMax({onComplete: createDragger, delay: 1});

initTimeline.to("#dragger", 1, {x: 500});
initTimeline.to("#theSquare", 1, {attr: {x: -450}}, 0);

$buttons.click(slide);

function slide() {
  var butIndex = $buttons.index($(this));
  var newY = butIndex * 700;
  if (newY === startY || TweenMax.isTweening(".allPics")) {
    return;
  } else {
    TweenMax.to(".allPics", 1, {y: -newY});
    TweenMax.to(".allCaptions", 1, {y: -newY / 7});
    startY = newY;
  }
}

function createDragger() {
  Draggable.create("#dragger", {
    type: "x",
    bounds: {
      minX: 0,
      maxX: 1000
    },
    throwProps: true,
    edgeResistance: 1,
    onDrag: moveMask,
    onThrowUpdate: moveMask
  });
}

function moveMask() {
  TweenMax.set("#theSquare", {attr: {x: this.x - 950}});
}

External CSS

  1. https://fonts.googleapis.com/css?family=Roboto:400,700&amp;#39;

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js
  3. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/ThrowPropsPlugin.min.js
  4. //cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/utils/Draggable.min.js