JSFiddle - React, Tailwind, and code Playground

HTML

<label>Iterations: <input id="iterations" type="number" value="20000000" step="5000000" /></label>

<div id="container">
    <div id="contents">
        Pannable container contents...
    </div>
</div>

CSS

#container {
  height: 400px;
  width: 800px;
  background-color: #ccc;
  overflow: hidden;
  cursor: -webkit-grab;
  cursor: -moz-grab;
  cursor: grab;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}

#container:active {
  cursor: move;
  cursor: -webkit-grabbing;
  cursor: -moz-grabbing;
  cursor: grabbing;
}

JavaScript

var container = document.getElementById("container");
var contents = document.getElementById("contents");
var input = document.getElementById("iterations");

var posX = 100;
var posY = 100;
var previousX = null;
var previousY = null;

var mousedownHandler = function (e) {
    window.onmousemove = globalMousemoveHandler;
    window.onmouseup = globalMouseupHandler;
    previousX = e.clientX;
    previousY = e.clientY;
}

var globalMousemoveHandler = function (e) {
    var now = Date.now();
    for (var i = 0, n = parseInt(input.value); i < n; i++);
    var elapsed = Date.now() - now;

    posX += e.clientX - previousX;
    posY += e.clientY - previousY;
    previousX = e.clientX;
    previousY = e.clientY;
    contents.style.transform = "translate3d(" + posX + "px, " + posY + "px, 0)";
    contents.innerText = elapsed + "ms";
}

var globalMouseupHandler = function (e) {
    window.onmousemove = null;
    window.onmouseup = null;
    previousX = null;
    previousY = null;
}

container.onmousedown = mousedownHandler;
contents.style.transform = "translate3d(" + posX + "px, " + posY + "px, 0)";