fully calculate paddings with js

This commit is contained in:
Oskar Wickström
2024-08-27 17:43:18 +02:00
parent 255d2c5805
commit 487d73465d
2 changed files with 51 additions and 42 deletions

View File

@@ -179,18 +179,8 @@ p {
} }
img, video { img, video {
--real-height: 100% / var(--ratio);
display: block; display: block;
width: 100%; width: 100%;
padding-bottom: calc(
round(
up,
var(--real-height),
var(--line-height)
)
- var(--real-height)
);
object-fit: contain; object-fit: contain;
} }

View File

@@ -15,48 +15,67 @@ function gridCellDimensions() {
return { width: rect.width, height: rect.height }; return { width: rect.width, height: rect.height };
} }
const defaultRatio = 16/9;
// Set the ratio variable on each media. // Set the ratio variable on each media.
function setRatios() { function setRatios() {
const cell = gridCellDimensions();
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) {
const rect = media.getBoundingClientRect();
const ratio = width / height;
const realHeight = rect.width / ratio;
const diff = cell.height - (realHeight % cell.height);
media.style.setProperty("padding-bottom", `${diff}px`);
}
}
const medias = document.querySelectorAll("img, video"); const medias = document.querySelectorAll("img, video");
for (media of medias) { for (media of medias) {
function onLoaded() { switch (media.tagName) {
var ratio = defaultRatio; case "IMG":
switch (media.tagName) { if (media.complete) {
case "IMG": onMediaLoaded(media);
ratio = media.naturalWidth / media.naturalHeight; } else {
break; media.addEventListener("load", () => onMediaLoaded(media));
case "VIDEO": media.addEventListener("error", function() {
ratio = media.videoWidth / media.videoHeight; console.error(media);
break; });
} }
if (ratio != NaN) { break;
console.log("Setting ratio", ratio, "for element", media); case "VIDEO":
media.style.setProperty("--ratio", ratio); 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() {
console.error(media);
});
break;
}
break;
} }
switch (media.tagName) {
case "IMG":
if (!media.loaded) {
media.style.setProperty("--ratio", defaultRatio); // default while loading
firstEvent(media, "load").then(onLoaded);
console.log("Image loaded", media);
}
break;
case "VIDEO":
if (media.readyState != 4) {
media.style.setProperty("--ratio", defaultRatio); // default while loading
firstEvent(media, "loadeddata").then(onLoaded);
console.log("Video ready", media);
}
break;
}
onLoaded();
} }
} }
setRatios(); setRatios();
window.addEventListener("load", setRatios);
window.addEventListener("resize", setRatios);
function checkOffsets() { function checkOffsets() {
const ignoredTagNames = new Set([ const ignoredTagNames = new Set([