👔Element+boxes
Last updated
Last updated
browser ⟩ DOM ⟩ type ⟩ Element ⟩ +boxes
extend Element with various box models.
.paddingBox = content + padding
.borderBox = content + padding + border (+ scrollbars, if present) (a Rect relative to .offsetParent)
.boundingBox - a Rect relative to viewport.
.scrollBox = content + padding + overflow
👉 compare: mouse event, elem.position()
replit ⟩ various boxes , require -> Rect
// 2023.01.18 - 16:30 (+) ._box (refactor), .toString(), viewport
// 2023.01.17 - 21:09 (•) first draft
// -----------------------------------------------
const {log} = console;
// ⭐️ import
import {rect} from './Rect.js'; // 👔 Rect
// -----------------------------------------------
// ⭐️ viewport
// -----------------------------------------------
// .size, .width, .height
// .origin, .x, .y
// -----------------------------------------------
// .toString()
//
const viewport = {
// private
get _box() {
const {scrollX: x, scrollY: y} = window;
const {innerWidth: w, innerHeight: h} = window;
return rect(x, y, w, h); // 👔 Rect
},
// 🔸 .size
get size() { return this._box.size },
get width() { return this.size.width }, // .width
get height() { return this.size.height }, // .height
// 🔸 .origin (relative to document)
get origin() { return this._box.origin },
get x() { return this.origin.x }, // .x
get y() { return this.origin.y }, // .y
// .toString()
toString() { return this._box.toString() }
};
// ⭐️ Element + box models
// -----------------------------------------------
// 🔸 .paddingBox - Rect properties + .info
// 🔸 .borderBox - Rect properties + .info
// 🔸 .boundingBox - Rect properties + .info
// 🔸 .scrollBox
//
Object.defineProperties(Element.prototype, {
// 🔸 .paddingBox
paddingBox: {
get() {
const {clientLeft: x, clientTop: y} = this;
const {clientWidth: width, clientHeight: height} = this;
const box = rect(x, y, width, height); // 👔 Rect
box.info = [
`🔲 padding box`,
`---------------`,
`• size: ${box.size}`,
` (❗ inline elements / elements with no CSS: return (0,0))`,
`• origin: ${box.origin}`,
` (⭐️ relative to its "border box")`,
` (❗ inline elements (like <i>, <code> ...): return (0,0))`,
].join('\n');
return box;
},
},
// 🔸 .borderBox
borderBox: {
get() {
const {offsetLeft: x, offsetTop: y} = this;
const {offsetWidth: width, offsetHeight: height} = this;
const box = rect(x, y, width, height); // 👔 Rect
box.info = [
`🔲 border box`,
`---------------`,
`• size: ${box.size}`,
`• origin: ${box.origin}`,
` (⭐️ relative to its "offsetParent")`,
`• offsetParent: ${this.offsetParent ?. nodeName ?? 'null'}`,
` (❗ returns "null" if the element: )`,
` • display : none (or its parent)`,
` • position: fixed`,
` • is <html> or <body>`,
].join('\n');
return box;
},
},
// 🔸 .boundingBox
boundingBox: {
get() {
const {x, y, width, height} = this.getBoundingClientRect();
const box = rect(x, y, width, height); // 👔 Rect
box.info = [
`🔲 bounding box`,
`----------------`,
`• size: ${box.size}`,
`• origin: ${box.origin}`,
` (⭐️ relative to the "viewport")`,
].join('\n');
return box;
},
},
// 🔸 .scrollBox
scrollBox: {
get() {
const {scrollLeft: x, scrollTop: y} = this;
const {scrollWidth: width, scrollHeight: height} = this;
const box = rect(x, y, width, height); // 👔 Rect
box.info = [
`🔲 scroll box`,
`----------------`,
`• size: ${box.size}`,
` (= padding box size, if no overflow.)`,
`• origin: ${box.origin}`,
` (⭐️ relative to its "origin", = (0,0) if it can't scroll.)`,
].join('\n');
return box;
},
},
});
// export
export {viewport}; // ES module export
scroll progress - use viewport.
scroll me - use .paddingBox, .scrollBox.
0: (?) first recorded
// ⭐️ viewport
const viewport = {
// .size
get size() {
return vec(innerWidth, innerHeight);
},
// .positionInDocument
get positionInDocument() {
return vec(scrollX, scrollY);
}
};
// ⭐️ extending `Element`
// 🔸 .paddingBox
// 🔸 .borderBox
// 🔸 .boundingBox ≈ .borderBox (integer-valued)
// 🔸 .scrollBox
Object.defineProperties(Element.prototype, {
// key = "paddingBox"
paddingBox: {
// access descriptor ()
get() {
// save element for future reference
const elem = this;
// return an object
return {
// .paddingBox.size (Vector)
get size() {
return vec(elem.clientWidth, elem.clientHeight);
},
};
},
},
// key = "borderBox"
borderBox: {
// access descriptor
get() {
// save element for future reference
const elem = this;
// return an object
return {
// .borderBox.size (Vector)
get size() {
return vec(elem.offsetWidth, elem.offsetHeight);
},
// .borderBox.position()
position(coordSystem){
// #TODO <-----------------------
switch(coordSystem){
default: return vec(elem.offsetLeft, elem.offsetTop)
}
}
};
},
},
// key = "boundingBox"
boundingBox: {
// access descriptor
get() {
// save element for future reference
const elem = this;
// return an object
return {
// .boundingBox.size (Vector)
get size() {
const {width, height} = elem.getBoundingClientRect();
return vec(width, height);
},
};
},
},
// key = "scrollBox"
scrollBox: {
// access descriptor
get() {
// save element for future reference
const elem = this;
//return an object
return {
// .scrollBox.size (Vector)
get size() {
return vec(elem.scrollWidth, elem.scrollHeight);
},
};
},
},
});bo