JSFiddle - React, Tailwind, and code Playground

by Josh Shields

HTML

<canvas width="560" height="320" id="canvasEl"></canvas>

JavaScript

(function(){
	var canvas = document.getElementById("canvasEl");
	var context = canvas.getContext("2d");
	var rx1 = 140, ry1 = 100, rx2 = 260, ry2 = 220, cx = 440, cy = 160, cr = 40;
	var mx = 0, my = 0, qx = 0, qy = 0;
	var min = Math.min;
	var max = Math.max;
	function clamp(v, x, y) {
		return v < x ? x : v > y ? y : v;
	}
	function dist(x1, y1, x2, y2) {
		var dx = x1 - x2, dy = y1 - y2;
		return Math.sqrt(dx * dx + dy * dy);
	}
	function p2c(px, py, cx, cy, cr) {
		return dist(px, py, cx, cy) < cr;
	}
	function r2c(rx1, ry1, rx2, ry2, cx, cy, cr) {
		return dist(clamp(cx, rx1, rx2), clamp(cy, ry1, ry2), cx, cy) < cr;
	}
	function p2r(px, py, rx1, ry1, rx2, ry2) {
		return px > rx1 && py > ry1 && px < rx2 && py < ry2;
	}
	context.strokeCircle = function(x, y, r) {
		this.beginPath();
		this.arc(x, y, r, 0, Math.PI * 2, false);
		this.closePath();
		this.stroke();
	}
	var hx, hy, hr = 7; // handle data
	var over = -1, dragging = false;
	function render() {
		var time = 0 | new Date(), x, y;
		updateTime = time + 25;
		//
		context.clearRect(0, 0, 640, 320);
		//
		if (over >= 0 && dragging) {
			x = mx - qx;
			y = my - qy;
			switch (over) {
				case 0:
					cx += x - hx; qx = mx - hx;
					cy += y - hy; qy = my - hy;
					break;
				case 1: cr = max(16, dist(cx, cy, x, y)); break;
				case 2: rx1 = min(x, rx2 - 16); ry1 = min(y, ry2 - 16); break;
				case 3: rx2 = max(x, rx1 + 16); ry1 = min(y, ry2 - 16); break;
				case 4: rx1 = min(x, rx2 - 16); ry2 = max(y, ry1 + 16); break;
				case 5: rx2 = max(x, rx1 + 16); ry2 = max(y, ry1 + 16); break;
				case 6: ry1 = min(y, ry2 - 16); break;
				case 7: ry2 = max(y, ry1 + 16); break;
				case 8: rx1 = min(x, rx2 - 16); break;
				case 9: rx2 = max(x, rx1 + 16); break;
				case 10:
					rx1 += x - hx;
					ry1 += y - hy;
					rx2 += x - hx;
					ry2 += y - hy;
					qx = mx - hx;
					qy = my - hy;
					break;
			}
		}
		//
		var co = r2c(rx1, ry1, rx2, ry2, cx, cy, cr);
		context.strokeStyle = co ? "red" :...