Initial project structure commit.
Static directory for public folders and business logic for the app within internal, split into domain specific folders to keep clear seperation of concerns.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
function gridCellDimensions() {
|
||||
const element = document.createElement("div");
|
||||
element.style.position = "fixed";
|
||||
element.style.height = "var(--line-height)";
|
||||
element.style.width = "1ch";
|
||||
document.body.appendChild(element);
|
||||
const rect = element.getBoundingClientRect();
|
||||
document.body.removeChild(element);
|
||||
return { width: rect.width, height: rect.height };
|
||||
}
|
||||
|
||||
// Add padding to each media to maintain grid.
|
||||
function adjustMediaPadding() {
|
||||
const cell = gridCellDimensions();
|
||||
|
||||
function setHeightFromRatio(media, ratio) {
|
||||
const rect = media.getBoundingClientRect();
|
||||
const realHeight = rect.width / ratio;
|
||||
const diff = cell.height - (realHeight % cell.height);
|
||||
media.style.setProperty("padding-bottom", `${diff}px`);
|
||||
}
|
||||
|
||||
function setFallbackHeight(media) {
|
||||
const rect = media.getBoundingClientRect();
|
||||
const height = Math.round((rect.width / 2) / cell.height) * cell.height;
|
||||
media.style.setProperty("height", `${height}px`);
|
||||
}
|
||||
|
||||
function onMediaLoaded(media) {
|
||||
var width, height;
|
||||
switch (media.tagName) {
|
||||
case "IMG":
|
||||
width = media.naturalWidth;
|
||||
height = media.naturalHeight;
|
||||
break;
|
||||
case "VIDEO":
|
||||
width = media.videoWidth;
|
||||
height = media.videoHeight;
|
||||
break;
|
||||
}
|
||||
if (width > 0 && height > 0) {
|
||||
setHeightFromRatio(media, width / height);
|
||||
} else {
|
||||
setFallbackHeight(media);
|
||||
}
|
||||
}
|
||||
|
||||
const medias = document.querySelectorAll("img, video");
|
||||
for (media of medias) {
|
||||
switch (media.tagName) {
|
||||
case "IMG":
|
||||
if (media.complete) {
|
||||
onMediaLoaded(media);
|
||||
} else {
|
||||
media.addEventListener("load", () => onMediaLoaded(media));
|
||||
media.addEventListener("error", function() {
|
||||
setFallbackHeight(media);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "VIDEO":
|
||||
switch (media.readyState) {
|
||||
case HTMLMediaElement.HAVE_CURRENT_DATA:
|
||||
case HTMLMediaElement.HAVE_FUTURE_DATA:
|
||||
case HTMLMediaElement.HAVE_ENOUGH_DATA:
|
||||
onMediaLoaded(media);
|
||||
break;
|
||||
default:
|
||||
media.addEventListener("loadeddata", () => onMediaLoaded(media));
|
||||
media.addEventListener("error", function() {
|
||||
setFallbackHeight(media);
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adjustMediaPadding();
|
||||
window.addEventListener("load", adjustMediaPadding);
|
||||
window.addEventListener("resize", adjustMediaPadding);
|
||||
|
||||
function checkOffsets() {
|
||||
const ignoredTagNames = new Set([
|
||||
"THEAD",
|
||||
"TBODY",
|
||||
"TFOOT",
|
||||
"TR",
|
||||
"TD",
|
||||
"TH",
|
||||
]);
|
||||
const cell = gridCellDimensions();
|
||||
const elements = document.querySelectorAll("body :not(.debug-grid, .debug-toggle)");
|
||||
for (const element of elements) {
|
||||
if (ignoredTagNames.has(element.tagName)) {
|
||||
continue;
|
||||
}
|
||||
const rect = element.getBoundingClientRect();
|
||||
if (rect.width === 0 && rect.height === 0) {
|
||||
continue;
|
||||
}
|
||||
const top = rect.top + window.scrollY;
|
||||
const left = rect.left + window.scrollX;
|
||||
const offset = top % (cell.height / 2);
|
||||
if(offset > 0) {
|
||||
element.classList.add("off-grid");
|
||||
console.error("Incorrect vertical offset for", element, "with remainder", top % cell.height, "when expecting divisible by", cell.height / 2);
|
||||
} else {
|
||||
element.classList.remove("off-grid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const debugToggle = document.querySelector(".debug-toggle");
|
||||
function onDebugToggle() {
|
||||
document.body.classList.toggle("debug", debugToggle.checked);
|
||||
}
|
||||
debugToggle.addEventListener("change", onDebugToggle);
|
||||
onDebugToggle();
|
||||
Reference in New Issue
Block a user