JSFiddle - React, Tailwind, and code Playground

CSS variables test for dragging an element with scaling slider

by Travis Almand

HTML

<p>This is just an experiment, not worth actually using.</p>
<input id="size" type="range" min="1" max="3" step="0.01" value="1" />
<div id="container">
  <div id="box"><div>
</div>

CSS

:root {
  --size: 20px;
  --x: 0;
  --y: 0;
  --targetX: 0;
  --targetY: 0;
  --boundLeft: 0;
  --boundTop: 0;
}

#container {
  border: 1px solid black;
  height: 200px;
  margin: 20px auto;
  overflow: hidden;
  width: 200px;
}

#box {
  background-color: gainsboro;
  height: 20px;
  transform: translate3d(calc(var(--x) - var(--boundLeft)), calc(var(--y) - var(--boundTop)), 0) scale3d(var(--size), var(--size), 1);
  width: 20px;
}

JavaScript

var $size = document.querySelector('#size');
var $container = document.querySelector('#container');
var $box = document.querySelector('#box');
var bounds;

function drag(e) {
  var x = e.clientX;
  var y = e.clientY;
  var targetX = $box.getBoundingClientRect().left;
  var targetY = $box.getBoundingClientRect().top;

  if (x > bounds.left && x < bounds.right - $box.offsetWidth && y > bounds.top && y < bounds.bottom - $box.offsetHeight) {
    document.documentElement.style.setProperty('--x', x + 'px');
    document.documentElement.style.setProperty('--y', y + 'px');
    document.documentElement.style.setProperty('--targetX', targetX + 'px');
    document.documentElement.style.setProperty('--targetY', targetY + 'px');
  }
}

$size.addEventListener('input', function (e) {
  document.documentElement.style.setProperty('--size', e.target.value);
});

$container.addEventListener('mousedown', function () {
	bounds = $container.getBoundingClientRect();
  
	document.documentElement.style.setProperty('--boundLeft', bounds.left + 'px');
  document.documentElement.style.setProperty('--boundTop', bounds.top + 'px');
	document.addEventListener('mousemove', drag);
});
$container.addEventListener('mouseup', function () {
	document.removeEventListener('mousemove', drag);
});