Making DOM APIs give you plain old rectangles which you can manipulate.
Have you ever considered how the randomness of JavaScript APIs complicates web app programming, similar to how Roman numerals make addition challenging?
To simplify application code one needs to think about how to abstract in a way which simplifies the code and takes you back to more fundamental ideas of geometry.
The APIs we use have evolved over decades without a unified design approach, making them less than ideal for data representation. Rather than a deliberate design, they've grown organically.
To simplify development, we aim to abstract these APIs, making them more intuitive to use and reducing the need for rote memorization, allowing for simpler logic.
See DOM ElementPreview
Popular frameworks often gain popularity due to social factors rather than technical superiority. They are usually promoted by large companies like Facebook and Google. People typically choose these frameworks because:
Learning this framework could lead to job opportunities at companies seeking these specific skills.
Employers prefer them because it's easier to find skilled workers.
Thus, frameworks often become popular for reasons beyond their technical merits.
Web APIs are like connectors that haven't been standardized. They seem compatible at first glance, but upon closer inspection, they resemble a nonsensical diagram from ChatGPT:
As opposed to really working and being compatible:
As a capable web developer our task is to work with the existing APIs to make them compatible.
Rectangles are a basic concept in geometry, and a webpage consists of a tree of rectangles.
In web development, the DOM API includes a representation of rectangles called DOMRect. However, using DOMRect can be cumbersome because different APIs provide them in a read-only format and sometimes use various units that are inconvenient.
Here’s a straightforward way to represent a rectangle in JavaScript:
function RECTrectable(){
return {
top : 0,
left : 0,
width : 10,
height : 10
}
}The built-in APIs provide DOMRect objects that are often read-only, which can be inconvenient.
Instead, let's create our own simple JavaScript rectangle objects by copying the properties:
function RECTcopy(I){
return {
top : I.top,
left : I.left,
width : I.width,
height : I.height
};
}
function RECTbounding(E){
return RECTcopy(E.getBoundingClientRect());
}
// We can call:
let E = document.querySelector(".DOCmainBody");
let Rect = RECTbounding(E);In the context of web design and development, the 'viewport' refers to the visible area of a web page that a user can see on their screen. It is the part of the browser window in which the web content is displayed, excluding any browser toolbars, scrollbars, and the window frame itself.
However, the viewport often presents in an awkward form—not as a rectangle but as 4 properties of the window object with arbitrary names.
Let's create a function that represents it simply as a rectangle.
function RECTviewport(){
return {
top : window.scrollY,
left : window.scrollX,
width : window.innerWidth,
height : window.innerHeight
}
}Likewise, if you have a div that is scrollable, then annoyingly the API uses its own wonky format. Not to worry, we can standardize that to our rectangle object. Then we can use:
function RECTscrollRect(E){
return {
top : E.scrollTop,
left : E.scrollLeft,
width : E.clientWidth,
height : E.clientHeight
}
}Suppose we want to convert the coordinates of an element’s bounding rectangle from absolute coordinates to physical coordinates on the screen—we need to add the viewport rectangle to the bounding rectangle.
Like this:
function RECTadd(R1, R2){
let R = RECTcopy(R1);
R.left += R2.left;
R.top += R2.top;
return R;
}
function APP(){
let E = document.querySelector(".DOCmainBody");
let AbsoluteRect = RECTadd(RECTbounding(E),RECTviewport());
}It’s useful to be able to calculate the intersection of two rectangles. This operation is not only helpful but also becomes easy to perform. In the case of my editor application, I need this function to determine how to 'clip' or hide my virtual cursor, which is simply a div tag.
function RECTintersection(R1, R2){
let R = {
top : Math.max(R1.top, R2.top),
left : Math.max(R1.left, R2.left)
};
R.width = Math.min(R1.left + R1.width, R2.left + R2.width) - R.left;
R.height = Math.min(R1.top + R1.height, R2.top + R2.height) - R.top;
if (R.width > 0 && R.height > 0){
return R;
}
return null;
}Finally, a function that can move an element, like a div, or create one on the fly using the rectangle data structure proves to be helpful:
function RECTmove(R, E){
let S = E.style;
S.top = R.top + "px";
S.left = R.left + "px";
S.width = R.width + "px";
S.height = R.height + "px";
}
function RECTquickDraw(R, Color) {
const D = document.createElement("div");
let S = D.style;
S.position = "absolute";
S.border = "1px solid " + Color;
RECTmove(R, D);
document.body.appendChild(D);
}Here is the source code:
https://bitbucket.org/interfaceware/concepts/src/main/concepts/web/RECT/RECTcore.js