JSFiddle - React, Tailwind, and code Playground
by TeWu
HTML
<div>Move the cursor inside the red rectangle, try it! :)</div>
<div>
<canvas id="bg-canvas" style="position: absolute; top: 10; left: 10;"></canvas>
<canvas id="point-canvas" style="position: absolute; top: 10; left: 10;"></canvas>
</div>
JavaScript
/////// INPUTS /////////////////
const w = 220;
const h = 115;
const p1 = {x:-79, y:80 };
const p2 = {x:9, y:-96};
const p3 = {x:55, y:-72};
const p4 = {x:-34, y:105};
////////////////////////////////
// Creates transformation matrix to transform
// from rectangle somewhere in 2D space with coordinates p0, px, pi, py
// to rectangle with coordinates (x=0, y=0), (x=w, y=0), (x=w, y=h), (x=0, y=h).
// Note that: p0 is mapped to (x=0, y=0)
// px is mapped to (x=w, y=0)
// py is mapped to (x=0, y=h)
const createTransformationMatrix = function(p0, px, py, w, h) {
// Translate px and py by p0 - pxt and pyt are px and py vectors in coordinate system in which p0 is at the origin
const pxt = {
x: px.x - p0.x,
y: px.y - p0.y,
};
const pyt = {
x: py.x - p0.x,
y: py.y - p0.y,
};
// Create transformation matrix matrix, which is inverse of transformation matrix that:
// 1. Transforms (x=0, y=0) to (x=p0.x, y=p0.y)
// 2. Transforms (x=1, y=0) to (x=p0.x + pxt.x / w, y=p0.y + pxt.y / w)
// 3. Transforms (x=0, y=1) to (x=p0.x + pyt.x / h, y=p0.y + pyt.y / h)
return Matrix.invert3([
[pxt.x / w, pyt.x / h, p0.x],
[pxt.y / w, pyt.y / h, p0.y],
[0 , 0 , 1 ],
]);
};
const transform = function(point, transformationMatrix) {
// Convert point to homogeneous coordinates
const inputVector = [
[point.x],
[point.y],
[1],
];
// Transform inputVector
const outputVector = Matrix.multiply(transformationMatrix, inputVector);
// Convert outputVector back to cartesian coordinates and return
return {
x: outputVector[0][0] / outputVector[2][0],
y: outputVector[1][0] / outputVector[2][0],
};
};
function docReady(fn) {
if (document.readyState === "complete" || document.readyState === "interactive") setTimeout(fn, 1);
else document.addEventListener("DOMContentLoaded", fn);
}
docReady(function() {
const canvas =...