我想让自定义元素内部不需要div元素,使图像的大小与div的大小相同,并使div的底部边框出现。另外,style元素应该在div中才能起作用,最好解决一下。除了那些东西之外,这段代码工作得很好。简单来说,html2canvas 缺少一些元素,所以我用 SVG 重新制作了它。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
class CaptureElement extends HTMLElement {
capture() {
const div = this.querySelector("div");
const br = document.createElement("br");
div.appendChild(br);
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const data = new XMLSerializer().serializeToString(div);
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${div.scrollWidth}" height="${div.scrollHeight}">
<foreignObject width="100%" height="100%">
${data}
</foreignObject>
</svg>`;
const img = new Image();
img.onload = () => {
canvas.width = div.scrollWidth;
canvas.height = div.scrollHeight;
context.drawImage(img, 0, 0);
const base64 = canvas.toDataURL("image/png");
console.log(base64);
div.removeChild(br);
if (this.hasAttribute("download")) {
var filename;
const download = this.getAttribute("download");
if (!download.endsWith(".png")) {
filename = download + ".png";
}
else {
filename = download;
}
const a = document.createElement('a');
a.href = base64;
a.download = filename;
a.click();
}
};
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
}
}
customElements.define("capture-element", CaptureElement);
document.addEventListener("DOMContentLoaded", () => {
document.querySelector("button").addEventListener("click", () => {
document.querySelector("capture-element").capture();
})
});
</script>
<style>
button {
color: white;
background-color: gray;
border-radius: 5px;
}
div.button {
text-align: center;
}
</style>
<title>Custom element</title>
</head>
<body>
<div class="button">
<button>Download</button>
</div>
<br>
<br>
<capture-element download="Certification.png">
<div id="certification">
<style>
* {
border: 0px;
background-color: white;
font-family: "Arial";
}
h1 {
background: linear-gradient(to right bottom, rgba(255, 188, 13, 1) 23%, rgba(0, 212, 255, 1));
font-weight: lighter;
color: transparent;
background-clip: text;
text-align: center;
}
p {
margin-left: 5px;
}
div#certification {
border-top: 1px solid black;
border-right: 1px solid black;
border-left: 1px solid black;
border-bottom: 2px solid black;
border-radius: 0px;
width: 50%;
min-width: 500px;
max-width: 1000px;
margin: auto;
}
.uname {
color: transparent;
font-weight: bolder;
font-size: xx-large;
text-align: center;
margin-top: 0px;
background: linear-gradient(to right bottom, rgb(132, 160, 68) 23%, rgb(66, 171, 192));
background-clip: text;
}
.fname {
font-weight: bold;
font-size: x-large;
text-align: center;
margin-right: 150px;
margin-top: 0px;
}
div:not(#certification) {
text-align: center;
}
</style>
<h1>Digital certification</h1>
<p>This certification is made for developers, from developers. This one is specially made for:</p>
<p class="uname">Username</p>
<p>From:</p>
<p class="fname">HTML, CSS, JavaScript</p>
<div>
<ruby><meter style="font-size: xx-large;" min="0" max="100" low="33" high="66" optimum="80"></meter>
<rt style="font-size: larger;">0%</rt>
</ruby>
</div>
</div>
</capture-element>
</body>
</html>
几乎没有改进来简化 capture-element 自定义元素的 HTML 和 JavaScript,确保内部 div 不需要显式声明,调整图像大小以匹配 div 大小,使 div 的底部边框出现,并确保在 SVG 序列化中正确捕获样式。 使用这个修改后的代码片段。