JSFiddle - React, Tailwind, and code Playground

by dumptyd

HTML

<button onclick="run()">Run</button>
<div id="app">
  <div class="line"></div>
  <div class="v"></div>
  <div class="origin"></div>
</div>

SCSS

#app {
  height: 100vh;
  width: 100%;
  position: relative;
  background: indigo;
}

.v {
  height: 4px;
  width: 4px;
  background-color: #ccc;
  position: absolute;
  left: 100px;
  top: 100px;
  transform-origin: bottom;
}
.origin {
  height: 4px;
  width: 4px;
  background-color: #ccc;
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: bottom;
}

.line {
  background-color: yellow;
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: top left;
  width: 2px;
}

JavaScript

const el = document.querySelector('.v');
const line = document.querySelector('.line');

let rect = el.getBoundingClientRect();
const [x1, y1] = [rect.x, rect.y];
console.log(x1, y1);

const um1 = [[1, 0], [0, 1]]; // identity matrix
// should become [1, 0], [1, 1] after transition finishes

const v = [x1, y1];

function pointDistance(p1, p2) {
    return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}

const run = () => {
  um1[1][0] += 0.01;
  const x2 = (v[0] * um1[0][0]) + (v[0] * um1[1][0]);
  const y2 = (v[1] * um1[0][1]) + (v[1] * um1[1][1]);
  console.log(x2, y2, x1, y1);
  el.style.left = `${x2}px`;
  el.style.top = `${y2}px`;
  
  line.style.height = pointDistance({ x: 0, y: 0 }, { x: x2, y: y2 }) + 'px';
  
  const slopeAngle = -Math.atan2(x2, y2);
 
  
  line.style.transform = `rotate(${slopeAngle}rad)`;
 
  if (um1[1][0] >= 1) return;
  setTimeout(() => run(), 50);
};
run();