Fast shot html element
当前为
// ==UserScript==
// @name WebShot
// @namespace http://tampermonkey.net/
// @version 2025-01-19
// @description Fast shot html element
// @author cxykevin
// @icon https://www.google.com/s2/favicons?sz=64&domain=0.1
// @match *://*/*
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function () {
GM_registerMenuCommand('Help', function () {
alert("点击 F12,找到你需要的元素,然后右键添加属性输入 shot 即可截图")
return true
});
GM_registerMenuCommand('Set Timeout -> 2s', function () {
GM_setValue("global_shot_timeout", 2000)
reg_menu()
return true
});
GM_registerMenuCommand('Set Timeout -> 10s', function () {
GM_setValue("global_shot_timeout", 10000)
reg_menu()
return true
});
var reg_1 = 0;
var reg_2 = 0;
function reg_menu() {
if (reg_1 != 0) {
GM_unregisterMenuCommand(reg_1)
}
if (reg_2 != 0) {
GM_unregisterMenuCommand(reg_2)
}
reg_1 = GM_registerMenuCommand('Timeout = ' + GM_getValue("global_shot_timeout", 2000) + "ms", function () {
var timeout = prompt("输入截图等待加载时间(单位ms,默认2000)")
timeout = timeout == null || timeout == "" ? 2000 : timeout
timeout = parseInt(timeout)
if (isNaN(timeout)) {
alert("请输入数字")
return true
}
GM_setValue("global_shot_timeout", timeout)
reg_menu()
return true
});
reg_2 = GM_registerMenuCommand('Scale = ' + GM_getValue("scale", 1), function () {
var scale_v = prompt("输入缩放倍数(小数)")
scale_v = scale_v == null || scale_v == "" ? 2000 : scale_v
scale_v = parseInt(scale_v)
if (isNaN(scale_v)) {
alert("请输入数字")
return true
}
GM_setValue("scale", scale_v)
reg_menu()
return true
});
}
reg_menu();
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/html-to-image.min.js'; script.type = "module";
document.head.appendChild(script);
async function expandImports(cssString, baseUrl) {
const importRegex = /@import\s+url\((['"]?)([^)'"]+)\1\);?/gi;
let imports = cssString.match(importRegex);
if (!imports) {
return cssString;
}
for (const importRule of imports) {
const urlMatch = importRule.match(/url\((['"]?)([^)'"]+)\1\)/);
if (urlMatch) {
const importedUrl = urlMatch[2];
const fullUrl = new URL(importedUrl, baseUrl).href;
try {
const response = await fetch(fullUrl);
if (response.ok) {
const importedCss = await response.text();
const expandedCss = await expandImports(importedCss, fullUrl);
cssString = cssString.replace(importRule, expandedCss);
} else {
console.warn(`Failed to load imported stylesheet: ${fullUrl}`);
}
} catch (error) {
console.error(`Error fetching imported stylesheet: ${fullUrl}`, error);
}
}
}
return cssString;
}
async function load_style() {
var all_style_str = ""
var query = document.querySelectorAll('style')
query.forEach(element => {
all_style_str += element.innerHTML + "\n"
})
const linkTags = document.querySelectorAll('link[rel="stylesheet"]');
for (const link of linkTags) {
const href = link.getAttribute('href');
try {
const response = await fetch(href);
if (response.ok) {
const cssContent = await response.text();
all_style_str += (cssContent + "\n");
} else {
console.warn(`Failed to load stylesheet: ${href}`);
}
} catch (error) {
console.error(`Error fetching stylesheet: ${href}`, error);
}
}
var res = extractAtRules(await expandImports(all_style_str))[0]
return res ? res : ""
}
function extractAtRules(cssString) {
const atRuleRegex = /@[\w-]+[^;{]*\{[^}]*\}/g;
const matches = cssString.match(atRuleRegex);
if (!matches) {
return [];
}
return matches;
}
function shot(el) {
if (el == undefined) {
throw new DOMError("找不到元素id")
}
var el_rect = el.getBoundingClientRect();
const boxShadowValues = window.getComputedStyle(el).boxShadow.split(" ");
var el_bx1 = 0
var el_bx2 = 0
var el_bx3 = 0
var el_bx4 = 0
var movex_el = 0
var movey_el = 0
var widthx_el = 0
var widthy_el = 0
if (boxShadowValues.length < 9) {
try {
el_bx1 = parseInt(boxShadowValues[4].replace(/px/g, ""))
el_bx2 = parseInt(boxShadowValues[5].replace(/px/g, ""))
el_bx3 = parseInt(boxShadowValues[6].replace(/px/g, ""))
el_bx4 = parseInt(boxShadowValues[7].replace(/px/g, ""))
movex_el = (el_bx3 * 2 + el_bx4 - el_bx1)
movey_el = (el_bx3 * 2 + el_bx4 - el_bx2)
widthx_el = (el_bx3 * 2 + el_bx4 + el_bx1) + movex_el
widthy_el = (el_bx3 * 2 + el_bx4 + el_bx2) + movey_el
} catch (e) { }
}
const allElements = document.body.querySelectorAll('*');
allElements.forEach(element => {
if (!el.contains(element)) {
element.style.cssText += "visibility:hidden !important;"
}
if (element.style.overflow != "visible" && element.style.overflow == "") {
element.style.overflow = "hidden"
}
});
el.style.transition = "none"
el.style.animation = "none"
el.style.visibility = "visible"
el.style.position = "fixed"
el.style.left = movex_el.toString() + "px"
el.style.top = movey_el.toString() + "px"
el.style.right = "none"
el.style.bottom = "none"
el.style.width = el_rect.width + "px"
el.style.height = el_rect.height + "px"
el.style.margin = "0px"
var real_w = el_rect.width + widthx_el
var real_h = el_rect.height + widthy_el
var v_doc = document.createElement('div')
v_doc.style.position = "fixed"
v_doc.style.left = "0px"
v_doc.style.top = "0px"
v_doc.style.width = real_w + "px"
v_doc.style.height = real_h + "px"
v_doc.style.transformOrigin = "0px 0px"
v_doc.style.backgroundColor = "#00000000"
v_doc.innerHTML = document.body.innerHTML
document.body.innerHTML = ""
document.body.appendChild(v_doc)
var query = document.querySelectorAll('iframe');
query.forEach(element => {
if (element.style.position == "static" || element.style.position == "") {
element.style.position = "relative"
}
})
load_style().then(styles => {
var styleelem = document.createElement('style');
styleelem.innerHTML = styles;
v_doc.appendChild(styleelem);
setTimeout(function () {
v_doc.style.transform = "scale(" + GM_getValue("scale", 1) + ")"
v_doc.style.width = real_w * GM_getValue("scale", 1) + "px"
v_doc.style.height = real_h * GM_getValue("scale", 1) + "px"
setTimeout(() => {
htmlToImage.toCanvas(v_doc)
.then(function (canvas) {
canvas.style.width = real_w + "px"
canvas.style.height = real_h + "px"
document.body.innerHTML = ""
document.body.appendChild(canvas);
canvas.toBlob((blob) => {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob, real_w, real_h);
link.download = 'domshot.png';
link.click();
setTimeout(function () {
location.reload()
}, 1000)
});
});
}, 0)
}, GM_getValue("global_shot_timeout", 2000))
});
}
window.shot = shot
setInterval(() => {
var ret = document.querySelector("[shot]")
if (ret) {
console.log("Shot! Element:", ret)
ret.attributes.removeNamedItem("shot")
shot(ret)
}
}, 500);
})();