Responsive Focus Point

Originally from: https://kmturley.blogspot.co.uk/2015/01/responsive-and-adaptive-images-using.html

HTML

<div id="FocusPoint">
  <div id="FpOriginal">
    <span id="FpTarget" style="left: {{ x }}%; top: {{ y }}%"></span>
    <img src="https://static.pexels.com/photos/167580/pexels-photo-167580.jpeg" alt="" id="FpSource" />
    <div id="FpInfo">x: 50%   y: 30%</div>
  </div>
  <div id="FpPreviews">
    <span id="FpPortrait" class="preview"></span>
    <span id="FpSquare" class="preview"></span>
    <span id="FpLandscape" class="preview"></span>
    <br/>
    <span id="FpWide" class="preview"></span>
  </div>
</div>

CSS

body {
  margin: 0;
}

/* focus point */

#FocusPoint {
  clear: both;
  overflow: hidden;
}

#FocusPoint img {
  max-width: 100%;
  max-height: calc(100vh - 220px);
  display: block;
}

#FpOriginal {
  display: inline-block;
  position: relative;
  overflow: hidden;
}

#FpSource {
  margin: 0 5px 5px 0;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

#FpTarget {
  margin: -50px 0 0 -50px;
  width: 100px;
  height: 100px;
  position: absolute;
  border: 1px solid #fff;
  -webkit-border-radius: 100%;
  -moz-border-radius: 100%;
  border-radius: 100%;
  pointer-events: none;
  left: 50%;
  top: 30%;
}

#FpPreviews {
  min-width: 410px;
  display: block;
}

#FpPreviews .preview {
  margin: 0 0 5px 5px;
  width: 100px;
  height: 100px;
  display: inline-block;
  background-size: cover;
}

#FpPortrait.preview {
  /* size on small mobile */
  width: 75px;
  background-size: 240%;
}

#FpSquare.preview {
  /* size on mobile */
  background-size: 200%;
}

#FpLandscape.preview {
  /* size on tablet */
  width: 207px;
}

#FpWide.preview {
  /* size on desktop */
  width: 500px;
}

#FpInfo {
  clear: both;
  position: absolute;
  bottom: 0;
  right: 0;
  color: black;
  padding: 5px 10px 8px 20px;
  text-shadow: 0px 0px 3px #aaa;
  background: rgba(255, 255, 255, 0.5);
  border-radius: 50px 0 0;
  font-family: sans-serif;
  font-size: 14px;
}

JavaScript

(function(MyNamespace) {
  "use strict";

  (function(FocusPoint) {
    var my = FocusPoint;
    my.element = document.querySelector("#FpSource");
    my.sourceContainer = document.querySelector("#FpOriginal");
    my.dragging = false;
    my.sourceUrl = my.element.getAttribute("src");
    my.exampleUrl = "url(\'" + my.sourceUrl + "\')";
    my.examples = document.querySelectorAll("#FpPreviews .preview");
    my.debugOut = document.querySelector("#FpInfo");
    my.defaultFocusPoint = "50% 30%";

    for (var ii = 0; ii < my.examples.length; ii++) {
      my.examples[ii].style.backgroundImage = my.exampleUrl;
      my.examples[ii].style.backgroundPosition = my.defaultFocusPoint;
    }

    my.debugOut.innerText = my.defaultFocusPoint;

    my.element.addEventListener("mousedown", function(e) {
      my.update(e);
      my.dragging = true;
    });

    my.element.addEventListener("mousemove", function(e) {
      if (my.dragging === true) {
        my.update(e);
      }
    });

    my.element.addEventListener("mouseup", function(e) {
      e.preventDefault();
      my.dragging = false;
    });

    my.element.addEventListener("mouseout", function(e) {
      e.preventDefault();
      my.dragging = false;
    });

    my.update = function(e) {
      e.preventDefault();
      var offset = my.offset(e.target);
      var x = Math.round(((e.pageX - offset.left) / e.target.clientWidth) * 100);
      var y = Math.round(((e.pageY - offset.top) / e.target.clientHeight) * 100);

      if (!my.targetElm) {
        my.targetElm = document.querySelector("#FpTarget");
      }

      my.targetElm.style.left = (e.pageX - my.sourceContainer.offsetLeft) + "px";
      my.targetElm.style.top = (e.pageY - my.sourceContainer.offsetTop) + "px";
      my.debugOut.innerText = x + "% " + y + "%";

      for (var ii = 0; ii < my.examples.length; ii++) {
        my.examples[ii].style.backgroundPosition = x + "% " + y + "%";
      }
    };

    my.offset = function(elm) {
      var body =...