【发布时间】:2011-02-13 12:28:17
【问题描述】:
能够将常规元素临时转换为canvas 将非常有用。例如,假设我有一个想要翻转的样式 div。我想动态创建一个画布,将HTMLElement“渲染”到画布中,隐藏原始元素并对画布进行动画处理。
可以吗?
【问题讨论】:
能够将常规元素临时转换为canvas 将非常有用。例如,假设我有一个想要翻转的样式 div。我想动态创建一个画布,将HTMLElement“渲染”到画布中,隐藏原始元素并对画布进行动画处理。
可以吗?
【问题讨论】:
在 MDN 上查看本教程:https://developer.mozilla.org/en/HTML/Canvas/Drawing_DOM_objects_into_a_canvas (archived)
它的关键技巧是:
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;
也就是说,它使用临时 SVG 图像 将 HTML 内容作为“外来元素”包含在内,然后将所述 SVG 图像渲染到画布元素中。但是,以这种方式可以在 SVG 图像中包含的内容有很大的限制。 (有关详细信息,请参阅“安全性”部分 - 由于隐私和跨域问题,基本上它比 iframe 或 AJAX 受到更多限制。)
【讨论】:
接下来的代码可以使用2种模式,模式1将html代码保存到图片,模式2将html代码保存到画布。
此代码适用于库:https://github.com/tsayen/dom-to-image
*“id_div”是要转换的元素html的id。
**“canvas_out”是包含画布的 div 的 id 所以试试这段代码。 :
function Guardardiv(id_div){
var mode = 2 // default 1 (save to image), mode 2 = save to canvas
console.log("Process start");
var node = document.getElementById(id_div);
// get the div that will contain the canvas
var canvas_out = document.getElementById('canvas_out');
var canvas = document.createElement('canvas');
canvas.width = node.scrollWidth;
canvas.height = node.scrollHeight;
domtoimage.toPng(node).then(function (pngDataUrl) {
var img = new Image();
img.onload = function () {
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
};
if (mode == 1){ // save to image
downloadURI(pngDataUrl, "salida.png");
}else if (mode == 2){ // save to canvas
img.src = pngDataUrl;
canvas_out.appendChild(img);
}
console.log("Process finish");
});
}
所以,如果你想保存到图像只需添加这个功能:
function downloadURI(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
}
使用示例:
<html>
<head>
</script src="/dom-to-image.js"></script>
</head>
<body>
<div id="container">
All content that want to transform
</div>
<button onclick="Guardardiv('container');">Convert<button>
<!-- if use mode 2 -->
<div id="canvas_out"></div>
</html>
评论是否可行。 评论 si les sirvio :)
【讨论】:
您可以使用dom-to-image 库(我是维护者)。
以下是解决问题的方法:
var parent = document.getElementById('my-node-parent');
var node = document.getElementById('my-node');
var canvas = document.createElement('canvas');
canvas.width = node.scrollWidth;
canvas.height = node.scrollHeight;
domtoimage.toPng(node).then(function (pngDataUrl) {
var img = new Image();
img.onload = function () {
var context = canvas.getContext('2d');
context.translate(canvas.width, 0);
context.scale(-1, 1);
context.drawImage(img, 0, 0);
parent.removeChild(node);
parent.appendChild(canvas);
};
img.src = pngDataUrl;
});
【讨论】:
您可以省去转换,您可以使用CSS3 Transitions 翻转<div> 和<ol> 以及您想要的任何HTML 标记。下面是一些带有源代码解释的demo,可以看看和学习:http://www.webdesignerwall.com/trends/47-amazing-css3-animation-demos/
【讨论】:
function convert() {
dom = document.getElementById('divname');
var script,
$this = this,
options = this.options,
runH2c = function(){
try {
var canvas = window.html2canvas([ document.getElementById('divname') ], {
onrendered: function( canvas ) {
window.open(canvas.toDataURL());
}
});
} catch( e ) {
$this.h2cDone = true;
log("Error in html2canvas: " + e.message);
}
};
if ( window.html2canvas === undefined && script === undefined ) {
} else {.
// html2canvas already loaded, just run it then
runH2c();
}
}
【讨论】:
为 DOM 元素设置动画最简单的解决方案是使用 CSS 过渡/动画,但我想您已经知道这一点,并且您尝试使用画布来完成 CSS 不允许您做的事情。 CSS custom filters 呢?如果您知道如何编写着色器,则可以以任何可以想象的方式转换您的元素。其他一些link 并且不要忘记检查CSS filter lab。
注意:您可能可以想象浏览器支持不好。
【讨论】:
在 natevw 引用的 Mozdev 帖子的基础上,我开始了一个小项目,在 Firefox、Chrome 和 Safari 中将 HTML 渲染到画布上。因此,例如,您可以简单地这样做:
rasterizeHTML.drawHTML('<span class="color: green">This is HTML</span>'
+ '<img src="local_img.png"/>', canvas);
源代码和更广泛的示例是here。
【讨论】:
没有,抱歉。
虽然规格说明:
2D 上下文 API 的未来版本可能会提供一种将使用 CSS 渲染的文档片段直接渲染到画布的方法。
这可能与您将得到的一样接近。
很多人想要ctx.drawArbitraryHTML/Element 类型的交易,但没有这样的内置功能。
唯一的例外是 Mozilla 独有的drawWindow,它将 DOM 窗口内容的快照绘制到画布中。此功能仅适用于以 Chrome(“仅限本地”)权限运行的代码。在普通的 HTML 页面中是不允许的。所以你可以用它来编写像 this one does 这样的 FireFox 扩展,仅此而已。
【讨论】:
有一个图书馆会尝试按照你说的去做。
查看此示例并获取代码
http://hertzen.com/experiments/jsfeedback/
http://html2canvas.hertzen.com/
从 html 读取 DOM 并将其渲染到画布上,在某些情况下会失败,但通常可以。
【讨论】:
抱歉,浏览器不会将 HTML 渲染到画布中。
如果可以的话,这将是一个潜在的安全风险,因为 HTML 可以包含来自第三方网站的内容(特别是图像和 iframe)。如果canvas 可以将 HTML 内容转换为图像,然后您读取图像数据,您就有可能从其他站点提取特权内容。
要从 HTML 中获取画布,您基本上必须使用 drawImage 和 fillText 从头开始编写自己的 HTML 渲染器,这可能是一项艰巨的任务。有one such attempt here,但它有点狡猾,距离完成还有很长的路要走。 (它甚至尝试从头开始解析 HTML/CSS,我认为这很疯狂!从应用了样式的真实 DOM 节点开始,并使用 getComputedStyle 和其中部分的相对位置读取样式会更容易使用offsetTop 等)
【讨论】:
<iframe src="https://example-online-bank.com/mystatement"> 在我的文档中包含一个目标页面,但我无法通过 DOM 访问该页面的内容,我应该无法通过截屏访问该信息。