将HTML元素渲染到<canvas>

got*_*ch4 36 html5 html5-canvas

有没有办法在画布中呈现任意HTML元素(然后访问其缓冲区......).

Mik*_*maa 26

<canvas>目前无法获得真正的HTML呈现,因为canvas上下文没有呈现HTML元素的功能.

有一些模拟:

html2canvas项目http://html2canvas.hertzen.com/index.html(基本上是在Javascript + canvas上构建的HTML渲染器)

<canvas>根据您的使用情况,可能会将HTML转换为SVG :

https://github.com/miohtama/Krusovice/blob/master/src/tools/html2svg2canvas.js

此外,如果您使用Firefox,您可以破解一些扩展权限,然后渲染DOM窗口<canvas>

https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_Graphics_with_Canvas?redirectlocale=en-US&redirectslug=Drawing_Graphics_with_Canvas#Rendering_Web_Content_Into_A_Canvas

  • html2canvas对于某些可以用大约20行代码完成的工作来说似乎完全是矫kill过正。 (2认同)

Sur*_*war 12

看看MDN

它将使用创建SVG图像渲染html元素.

例如:<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中.

这是将HTML元素添加到画布的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;
Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
Run Code Online (Sandbox Code Playgroud)

  • 对于来这里寻求启发的其他人:IE 不支持“foreignObject”。 (2认同)

Cpn*_*nch 6

这是将任意HTML渲染到画布中的代码:

function render_html_to_canvas(html, ctx, x, y, width, height) {
    var xml = nw.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;
}
Run Code Online (Sandbox Code Playgroud)

例:

function render_html_to_canvas(html, ctx, x, y, width, height) {
    var xml = nw.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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以在JSFiddle上提供一个演示(div +图片)吗?谢谢! (2认同)

小智 5

CSSelement()函数最终可能会帮助这里的一些人,尽管它不是问题的直接答案。它允许您使用一个元素(以及所有子元素,包括视频、跨域 iframe 等)作为背景图像(以及您通常url(...)在 CSS 代码中使用的任何其他位置)。这是一篇博客文章,展示了您可以用它做什么。

自 2011 年以来,它已在 Firefox 中实现,并且正在考虑在 Chromium/Chrome 中使用(如果您关心此功能,请不要忘记给该问题加星)。