将 HTML 元素渲染到 <canvas>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12652769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rendering HTML elements to <canvas>
提问by gotch4
Is there a way to have an arbitrary HTML element rendered in a canvas (and then access its buffer...).
有没有办法在画布中呈现任意 HTML 元素(然后访问其缓冲区......)。
采纳答案by Mikko Ohtamaa
You won't get real HTML rendering to <canvas>
per se currently, because canvas context does not have functions to render HTML elements.
您<canvas>
目前不会获得真正的 HTML 渲染本身,因为画布上下文没有渲染 HTML 元素的功能。
There are some emulations:
有一些模拟:
html2canvas project http://html2canvas.hertzen.com/index.html(basically a HTML renderer attempt built on Javascript + canvas)
html2canvas 项目http://html2canvas.hertzen.com/index.html(基本上是基于 Javascript + canvas 构建的 HTML 渲染器尝试)
HTML to SVG to <canvas>
might be possible depending on your use case:
<canvas>
根据您的用例,HTML 到 SVG可能是可能的:
https://github.com/miohtama/Krusovice/blob/master/src/tools/html2svg2canvas.js
https://github.com/miohtama/Krusovice/blob/master/src/tools/html2svg2canvas.js
Also if you are using Firefox you can hack some extendedpermissions and then render a DOM window to <canvas>
此外,如果您使用的是 Firefox,您可以破解一些扩展权限,然后将 DOM 窗口呈现给<canvas>
回答by Suresh Mahawar
Take a look on MDN
看看MDN
It will render html element using creating SVG images.
它将使用创建 SVG 图像来呈现 html 元素。
For Example:There is <em>I</em> like <span style="color:white; text-shadow:0 0 2px blue;">cheese</span>
HTML element. And I want to add it into <canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
Canvas Element.
例如:有<em>I</em> like <span style="color:white; text-shadow:0 0 2px blue;">cheese</span>
HTML 元素。我想将它添加到<canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
Canvas Element 中。
Here is Javascript Code to add HTML element to canvas.
这是将 HTML 元素添加到 canvas 的 Javascript 代码。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<em>I</em> like <span style="color:white; text-shadow:0 0 2px blue;">cheese</span>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svg = new Blob([data], {
type: 'image/svg+xml;charset=utf-8'
});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
}
img.src = url;
<canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
回答by CpnCrunch
Here is code to render arbitrary HTML into a canvas:
这是将任意 HTML 渲染到画布中的代码:
function render_html_to_canvas(html, ctx, x, y, width, height) {
var xml = html_to_xml(txt);
xml = xml.replace(/\#/g, '%23');
var data = "data:image/svg+xml;charset=utf-8,"+'<svg xmlns="http://www.w3.org/2000/svg" width="'+width+'" height="'+height+'">' +
'<foreignObject width="100%" height="100%">' +
xml+
'</foreignObject>' +
'</svg>';
var img = new Image();
img.onload = function () {
ctx.drawImage(img, x, y);
}
img.src = data;
}
function html_to_xml(html) {
var doc = document.implementation.createHTMLDocument('');
doc.write(html);
// You must manually set the xmlns if you intend to immediately serialize
// the HTML document to a string as opposed to appending it to a
// <foreignObject> in the DOM
doc.documentElement.setAttribute('xmlns', doc.documentElement.namespaceURI);
// Get well-formed markup
html = (new XMLSerializer).serializeToString(doc.body);
return html;
}
example:
例子:
const ctx = document.querySelector('canvas').getContext('2d');
const html = `
<p>this
<p>is <span style="color:red; font-weight: bold;">not</span>
<p><i>xml</i>!
<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABWElEQVQ4jZ2Tu07DQBBFz9jjvEAQqAlQ0CHxERQ0/AItBV9Ew8dQUNBQIho6qCFE4Nhex4u85OHdWAKxzfWsx0d3HpazdGITA4kROjl0ckFrnYJmQlJrKsQZxFOIMyEqIMpADGhSZpikB1hAGsovdxABGuepC/4L0U7xRTG/riG3J8fuvdifPKnmasXp5c2TB1HNPl24gNTnpeqsgmj1eFgayoHvRDWbLBOKJbn9WLGYflCCpmM/2a4Au6/PTjdH+z9lCJQ9vyeq0w/ve2kA3vaOnI6k4Pz+0Y24yP3Gapy+Bw6qdfsCRZfWSWgclCCVXTZu5LZFXKJJ2sepW2KYNCENB3U5pw93zLoDjNK6E7rTFcgbkGYJtiLckxCiw4W1OURsxUE5BokQiQj3JIToVtKwlhsurq+YDYbMBjuU/W3KtT3xIbrpAD7E60lwQohuaMtP8ldI0uMbGfC1r1zyWPUAAAAASUVORK5CYII=">`;
render_html_to_canvas(html, ctx, 0, 0, 300, 150);
function render_html_to_canvas(html, ctx, x, y, width, height) {
var data = "data:image/svg+xml;charset=utf-8," + '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '">' +
'<foreignObject width="100%" height="100%">' +
html_to_xml(html) +
'</foreignObject>' +
'</svg>';
var img = new Image();
img.onload = function() {
ctx.drawImage(img, x, y);
}
img.src = data;
}
function html_to_xml(html) {
var doc = document.implementation.createHTMLDocument('');
doc.write(html);
// You must manually set the xmlns if you intend to immediately serialize
// the HTML document to a string as opposed to appending it to a
// <foreignObject> in the DOM
doc.documentElement.setAttribute('xmlns', doc.documentElement.namespaceURI);
// Get well-formed markup
html = (new XMLSerializer).serializeToString(doc.body);
return html;
}
<canvas></canvas>
回答by Mohamed El Prince
RasterizeHTML is a very good project, but if you need to access the canvas it wont work on chrome. due to the use of <foreignObject>
.
RasterizeHTML 是一个非常好的项目,但是如果您需要访问画布,它在 chrome 上不起作用。由于使用<foreignObject>
.
If you need to access the canvas then you can use html2canvas
如果您需要访问画布,则可以使用 html2canvas
I am trying to find another project as html2canvas is very slow in performance
我正在尝试寻找另一个项目,因为 html2canvas 的性能非常慢
回答by Mohamed El Prince
The CSS element()
functionmay eventually help some people here, even though it's not a direct answer to the question. It allows you to use an element (and all children, including videos, cross-domain iframes, etc.) as a background image (and anywhere else that you'd normally use url(...)
in your CSS code). Here's a blog postthat shows what you can do with it.
CSSelement()
函数最终可能会帮助这里的一些人,即使它不是问题的直接答案。它允许您使用元素(以及所有子元素,包括视频、跨域 iframe 等)作为背景图像(以及您通常url(...)
在 CSS 代码中使用的任何其他地方)。这是一篇博客文章,展示了您可以用它做什么。
It has been implemented in Firefox since 2011, and is being consideredin Chromium/Chrome (don't forget to give the issue a star if you care about this functionality).
自 2011 年以来,它已在 Firefox 中实现,并且正在考虑在 Chromium/Chrome 中使用(如果您关心此功能,请不要忘记给该问题打个星)。
回答by Richard Otvos
According to the HTML specification you can't access the elements of the Canvas. You can get its context, and draw in it manipulate it, but that is all.
根据 HTML 规范,您无法访问 Canvas 的元素。您可以获取它的上下文,并在其中绘制并操作它,但仅此而已。
BUT, you can put both the Canvas and the html element in the same div with a aposition: relative
and then set the canvas and the other element to position: absolute
.
This ways they will be on the top of each other. Then you can use the left
and right
CSS properties to position the html element.
但是,您可以使用 aa 将 Canvas 和 html 元素放在同一个 div 中,position: relative
然后将画布和另一个元素设置为position: absolute
. 这样他们就会在彼此的顶部。然后您可以使用left
和right
CSS 属性来定位 html 元素。
If the element doesn't shows up, maybe the canvas is before it, so use the z-index
CSS property to bring it before the canvas.
如果元素没有出现,可能是画布在它之前,所以使用z-index
CSS 属性将它放在画布之前。