web-dev-qa-db-ja.com

HTML要素を<canvas>にレンダリングする

キャンバスに任意のHTML要素をレンダリングする方法はありますか(そして、そのバッファーにアクセスします...)。

34
gotch4

キャンバスコンテキストにはHTML要素をレンダリングする機能がないため、現在<canvas>自体に実際のHTMLレンダリングを取得することはできません。

いくつかのエミュレーションがあります。

html2canvasプロジェクト http://html2canvas.hertzen.com/index.html (基本的には、Javascript +キャンバス上に構築されたHTMLレンダラーの試み)

HTMLからSVGへの<canvas>は、ユースケースに応じて可能です。

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

25
Mikko Ohtamaa

[〜#〜] 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要素に追加したいと思います。

これは、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;
<canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
12
Suresh Mahawar

以下は、任意のHTMLをキャンバスにレンダリングするコードです。

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;
}

例:

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>
6
CpnCrunch

RasterizeHTMLは非常に優れたプロジェクトですが、キャンバスにアクセスする必要がある場合、クロムでは機能しません。 foreignObjectの使用により

キャンバスにアクセスする必要がある場合は、html2canvasを使用できます

Html2canvasのパフォーマンスが非常に遅いため、別のプロジェクトを見つけようとしています。

3

CSS element() function は、質問に対する直接的な答えではありませんが、最終的には一部の人々を助けるかもしれません。要素(およびビデオ、クロスドメインiframeなどを含むすべての子)を背景画像(および通常CSSコードでurl(...)を使用する他の場所)として使用できます。 これはブログ投稿です これで何ができるかを示しています。

2011年からFirefoxに実装されており、Chromium/Chromeでは 検討中 です(この機能に関心がある場合は、問題にスターを付けることを忘れないでください)。

1
user10898116

HTML仕様によると、Canvasの要素にアクセスすることはできません。そのコンテキストを取得し、その中に描画して操作できますが、それだけです。

ただし、Canvasとhtml要素の両方をaposition: relativeを使用して同じdivに配置してから、canvasと他の要素をposition: absoluteに設定できます。このように、彼らは互いの上になります。次に、leftおよびright CSSプロパティを使用して、html要素を配置できます。

要素が表示されない場合は、キャンバスがその前にある可能性があるため、z-index CSSプロパティを使用してキャンバスの前に配置します。

0
Richard Otvos