const SCREENSHOT_LIB = "https://cdn.jsdelivr.net/npm/modern-screenshot@4.7.0/+esm";
const PINK = "#ff79c6";
const outline = (node, style) => {
const saved = [node.style.outline, node.style.outlineOffset];
const bare = !node.getAttribute("style");
node.style.outline = style;
node.style.outlineOffset = "2px";
return () => {
[node.style.outline, node.style.outlineOffset] = saved;
if (bare && !node.style.length) node.removeAttribute("style");
};
};
const points = [];
const drawNumber = (context, n, x, y) => {
context.beginPath();
context.arc(x, y, 11, 0, 2 * Math.PI);
context.fillStyle = PINK;
context.fill();
context.lineWidth = 2;
context.strokeStyle = "#fff";
context.stroke();
context.fillStyle = "#1f2430";
context.font = "700 12px system-ui, -apple-system, sans-serif";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText(String(n), x, y + 0.5);
};
const pageCanvas = async () => {
const { domToCanvas } = await import(SCREENSHOT_LIB);
const page = document.documentElement;
const background = getComputedStyle(document.body).backgroundColor;
return domToCanvas(page, {
scale: 1,
width: innerWidth,
height: Math.max(page.scrollHeight, innerHeight),
backgroundColor: background === "rgba(0, 0, 0, 0)" ? "#ffffff" : background,
filter: (node) => node !== host,
});
};
const png = (canvas) =>
new Promise((resolve, reject) => {
canvas.toBlob((blob) => (blob ? resolve(blob) : reject(new Error("no picture"))), "image/png");
});
const crop = async ({ x, y, w, h }) => {
const canvas = await pageCanvas();
const ratio = canvas.width / innerWidth;
const part = document.createElement("canvas");
[part.width, part.height] = [Math.max(1, Math.round(w * ratio)), Math.max(1, Math.round(h * ratio))];
part.getContext("2d").drawImage(canvas, x * ratio, y * ratio, w * ratio, h * ratio, 0, 0, part.width, part.height);
return png(part);
};
const capture = async () => {
const boxes = points.map(({ node }, index) => ({ n: index + 1, shown: node.isConnected, rect: node.getBoundingClientRect() }));
const [left, top] = [scrollX, scrollY];
const canvas = await pageCanvas();
const ratio = canvas.width / innerWidth;
const context = canvas.getContext("2d");
context.setTransform(ratio, 0, 0, ratio, 0, 0);
for (const { n, shown, rect } of boxes) {
if (!shown) continue;
const [x, y] = [rect.left + left, rect.top + top];
context.lineWidth = 3;
context.strokeStyle = PINK;
context.strokeRect(x - 3.5, y - 3.5, rect.width + 7, rect.height + 7);
drawNumber(context, n, Math.max(12, x - 5), Math.max(12, y - 5));
}
return png(canvas);
};