// ==UserScript==
// @name wallhaven-layout
// @namespace http://tampermonkey.net/
// @version 2024-04-22
// @description wallhaven layout
// @author You
// @match https://wallhaven.cc/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=wallhaven.cc
// @require https://cdnjs.cloudflare.com/ajax/libs/decimal.js/9.0.0/decimal.min.js
// @grant none
// @license MIT
// ==/UserScript==
// import Decimal from "decimal.js";
(function () {
"use strict";
let width = document.querySelector("#thumbs")?.clientWidth - 20;
const load = () => {
getWallpaper();
const thumbs = document.querySelector("#thumbs");
const observerOptions = {
childList: true, // 观察目标子节点的变化,是否有添加或者删除
attributes: false, // 观察属性变动
subtree: false, // 观察后代节点,默认为 false
};
if (!thumbs) return;
const observer = new MutationObserver((mutations) => {
getWallpaper();
});
observer.observe(thumbs, observerOptions);
const resize = () => {
console.log(
"object :>> ",
document.querySelector("#thumbs")?.clientWidth
);
width = document.querySelector("#thumbs")?.clientWidth - 20;
getWallpaper();
};
window.addEventListener("resize", resize);
window.onunload = () => {
observer.disconnect();
window.removeEventListener("resize", resize);
};
};
function calcImageRow({ list, height, w, clientWidth, gap = 0 }) {
let grid = [
{
height: new Decimal(height),
list: [],
notFull: false,
},
];
let currentRowIndex = 0;
list.forEach((i) => {
const currentRow = grid[currentRowIndex];
const totalWidth = currentRow.list.reduce((acc, cur) => {
const width = new Decimal(currentRow.height).mul(cur.ratio);
return acc.add(width);
}, new Decimal(0));
/** 剩余宽度 */
const remainWidth = new Decimal(clientWidth).sub(totalWidth);
if (remainWidth.lt(w)) {
currentRowIndex++;
grid.push({
height: new Decimal(height),
list: [i],
notFull: false,
});
} else {
currentRow.list.push(i);
}
});
grid.forEach((row) => {
const totalWidth = row.list.reduce((acc, cur) => {
const width = new Decimal(row.height).mul(cur.ratio);
return acc.add(width);
}, new Decimal(0));
const totalRatio = row.list.reduce((acc, cur) => {
return acc.add(cur.ratio);
}, new Decimal(0));
const gapWidth = new Decimal(row.list.length + 1).mul(gap);
if (!totalWidth.plus(200).lt(clientWidth)) {
row.height = new Decimal(clientWidth).sub(gapWidth).div(totalRatio);
} else {
row.height = new Decimal(clientWidth).sub(gapWidth).div(totalRatio);
row.notFull = true;
}
});
return grid;
}
const getWallpaper = () => {
console.log("width :>> ", width);
const pages = document.querySelectorAll(".thumb-listing-page");
const pagesInfo = Array.from(pages).map((page) => {
page.style.textAlign = "left";
page.style.padding = 0;
page.style.paddingLeft = 10 + "px";
page.style.paddingBottom = 4 + "em";
page.style.height = page.scrollHeight + "px";
const imageDoms = page.querySelectorAll(".thumb-listing-page ul li");
return Array.from(imageDoms).map((imageDom) => {
const [w, h] =
imageDom
.querySelector(".thumb-info .wall-res")
?.textContent?.split(" x ") ?? [];
return {
url: imageDom.querySelector("img")?.dataset.src,
ratio: Number(new Decimal(w).div(h).toFixed(2)),
width: Number(w),
height: Number(h),
source: imageDom,
id: imageDom.querySelector("figure")?.dataset.wallpaperId,
};
});
});
const grids = pagesInfo.map((page, index) => {
return calcImageRow({
list: page,
height: 300,
w: 0,
clientWidth: width,
gap: 10,
});
});
console.log(grids, pagesInfo);
grids.forEach((grid) => {
grid.forEach((row, rowIndex) => {
row.list.forEach((image, index) => {
const { source: _source, height } = image;
const source = _source.querySelector("figure");
_source.style.verticalAlign = "top";
source.style.margin = 0;
source.style.marginRight = 10 + "px";
source.style.marginBottom = 10 + "px";
if (row.notFull && rowIndex === grid.length - 1) {
console.log("image :>> ", image, new Decimal(image.ratio).gt(1));
source.style.height = 300 + "px";
source.style.width = new Decimal(image.ratio).mul(300) + "px";
} else {
source.style.width = `${row.height.mul(image.ratio)}px`;
source.style.height = `${row.height}px`;
}
source.querySelector("img").style.height = `100%`;
source.querySelector("img").style.width = `100%`;
});
});
});
Array.from(document.querySelectorAll(".thumb-listing-page")).forEach(
(e) => {
const ulH = e.querySelector("ul").scrollHeight;
console.log("ulH :>> ", ulH);
e.style.marginTop = -e.style.scrollHeight - ulH + "px";
}
);
};
window.addEventListener("load", load);
// Your code here...
})();