JSFiddle - React, Tailwind, and code Playground
JavaScript
(function(){
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var focalDistance = 50;
var cameraDistance = 40;
var cx = 150;
var cy = 75;
var heading = 270 /180*Math.PI; // up
canvas.onmousemove = function(e) {
bearing = Math.PI * 2 * ((e.clientX - canvas.offsetLeft) / 300);
};
ctx.clearRect(0,0,300,150);
ctx.fillStyle = 'black';
ctx.fillText((heading/Math.PI*180).toFixed(0)+' \xb0 | '+(heading/Math.PI).toFixed(2)+' \u03c0', 10, 10);
// center
ctx.fillStyle = 'red';
ctx.fillRect(cx-1.5, cy-1.5, 3, 3);
// line forward on heading (black up to focal point, grey after)
ctx.strokeStyle = '#ccc';
ctx.beginPath();
ctx.moveTo(cx-.5, cy-.5);
ctx.lineTo(cx, cy-75);
ctx.stroke();
ctx.strokeStyle = 'black';
ctx.beginPath();
ctx.moveTo(cx-.5, cy-.5);
ctx.lineTo(cx, cy-focalDistance);
ctx.stroke();
// get coordinate of left cam (forward n px after turning left 90 degrees)
var lx = cameraDistance * Math.cos(heading-0.5*Math.PI);
var ly = cameraDistance * Math.sin(heading-0.5*Math.PI);
// line left
ctx.strokeStyle = 'black';
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(cx+lx, cy+ly);
ctx.stroke();
// left cam
ctx.fillStyle = 'green';
ctx.fillRect(cx+lx-1.5, cy+ly-1.5, 3, 3);
// angle from left cam to focal
var dangel = 0.5 * Math.PI - Math.atan(focalDistance / cameraDistance);
// line from camera through focus point
var fx = 2 * focalDistance * Math.cos(heading + dangel);
var fy = 2 * focalDistance * Math.sin(heading + dangel);
// left line beyond focus point
ctx.strokeStyle = '#ccc';
ctx.beginPath();
ctx.moveTo(cx+lx, cy+ly);
ctx.lineTo(cx+lx+fx, cy+ly+fy);
ctx.stroke();
// exact distance using pytho
var camd = Math.sqrt(cameraDistance * cameraDistance + focalDistance *...