Wie kann ich ein HTML-Element in ein Canvas-Element umwandeln?
Lesezeit: 8 Minuten
davemyron
Es wäre unglaublich nützlich, ein reguläres Element vorübergehend in ein umwandeln zu können canvas. Angenommen, ich habe ein gestyltes div dass ich umdrehen möchte. Ich möchte eine Leinwand dynamisch erstellen, die “rendern”. HTMLElement in die Leinwand, blenden Sie das ursprüngliche Element aus und animieren Sie die Leinwand.
Kann es getan werden?
Es gibt eine Bibliothek, die versucht, das zu tun, was Sie sagen.
Sehen Sie sich diese Beispiele an und erhalten Sie den Code
Liest das DOM aus dem HTML und rendert es auf eine Leinwand, schlägt bei einigen fehl, funktioniert aber im Allgemeinen.
Das ist hervorragend!! wirklich sehr genau, wenn man alle Faktoren berücksichtigt
– Alex
9. Februar 2012 um 20:07 Uhr
Entschuldigung, der Browser rendert HTML nicht in eine Zeichenfläche.
Es wäre ein potenzielles Sicherheitsrisiko, wenn Sie könnten, da HTML Inhalte (insbesondere Bilder und Iframes) von Websites Dritter enthalten kann. Wenn canvas HTML-Inhalt in ein Bild umwandeln und dann die Bilddaten lesen könnten, könnten Sie möglicherweise privilegierten Inhalt von anderen Websites extrahieren.
Um eine Leinwand aus HTML zu erhalten, müssten Sie im Grunde Ihren eigenen HTML-Renderer von Grund auf neu schreiben drawImage und fillText, was eine potentiell riesige Aufgabe ist. Es gibt ein solcher Versuch hier aber es ist ein bisschen zwielichtig und noch lange nicht fertig. (Es versucht sogar, das HTML/CSS von Grund auf neu zu analysieren, was ich für verrückt halte! Es wäre einfacher, von einem echten DOM-Knoten mit angewendeten Stilen aus zu beginnen und das Styling zu lesen getComputedStyle und relative Positionen von Teilen davon mit offsetTop et al.)
Nun, das ist ein Mist. Es wäre großartig, ein Element “einzufrieren” und es auf irgendeine Weise zu verzerren und es später wieder “auftauen” zu können. Ich bin anderer Meinung, dass es ein wäre Neu Sicherheitsrisiko. Es wäre nicht anders, als JS verwenden zu können, um das DOM zu lesen und diese Informationen zu stehlen (und natürlich würden alle Sandbox-Einschränkungen für JS dasselbe gelten). Danke für die Bestätigung dessen, was ich vermutete, wäre die Antwort, Bobince.
– davemyron
30. April 2010 um 21:07 Uhr
Ja, es ist nur so, dass das Anwenden von Beschränkungen auf denselben Ursprung für allgemeine HTML-Inhalte erheblich schwieriger wäre als für dokumentenübergreifendes Skripting. Sie müssten jedes Rechteck auf dem Bildschirm aufzeichnen, das Inhalte von Drittanbietern enthielt, und eine Renderanforderung ablehnen, die einen von ihnen schneidet – Bilder, Iframes, Video/Audio, Elemente mit Hintergrundbildern, alle Objekte/Einbettungen /applets, ob Drittanbieter oder nicht (da sie ihre eigenen Cross-Site-Regeln haben), SVG und so weiter.
– Bobin
30. April 2010 um 22:13 Uhr
Bei der Sicherheitsfrage muss ich widersprechen. Wenn Sie Zugriff auf ihre Seite haben, haben Sie sicherlich Zugriff auf mehr Informationen, als aus einer .png-Datei ihrer Seite entnommen werden können. Wenn die Seite verfügbar ist, öffnet ein Screenshot der Seite keine neuen Sicherheitslücken!
– BentFX
18. Mai 2011 um 18:17 Uhr
Sie können die Seite einer anderen Person in einen Rahmen oder auf andere Weise einbetten, ohne Skriptzugriff darauf zu haben. ich kann <iframe src="https://example-online-bank.com/mystatement"> um eine Zielseite in mein Dokument aufzunehmen, aber ich habe keinen Zugriff auf den Inhalt dieser Seite über DOM und ich sollte nicht in der Lage sein, auf diese Informationen durch Screenshots zuzugreifen.
– Bobin
18. Mai 2011 um 19:31 Uhr
„Um eine Leinwand aus HTML zu erhalten, müssten Sie im Grunde Ihren eigenen HTML-Renderer mit drawImage und fillText von Grund auf neu schreiben, was eine potenziell riesige Aufgabe ist.“ Aber wurde trotzdem gemacht, siehe die andere Antwort von Aristos. Es sollte die akzeptierte Antwort imo sein.
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;
Das heißt, es wurde ein Temporär verwendet SVG-Bild die einzubeziehen HTML content als “Fremdelement” und rendert dieses SVG-Bild dann in ein Canvas-Element. Es gibt jedoch erhebliche Einschränkungen hinsichtlich dessen, was Sie auf diese Weise in ein SVG-Bild einfügen können. (Weitere Informationen finden Sie im Abschnitt „Sicherheit“ – im Grunde ist es aufgrund von Datenschutz- und domänenübergreifenden Bedenken viel eingeschränkter als ein Iframe oder AJAX.)
Dies sollte die akzeptierte Antwort sein. Hat mir geholfen, meine API von roh auf DOM auf Leinwand (und dann auf ein Bild) zu schreiben!
– Panini-Mittagessen
26. April 2020 um 21:12 Uhr
danke für diese antwort. Wird das von allen Browsern unterstützt?
– Absturz
15. Januar 2021 um 6:15 Uhr
der alternative Link funktioniert nicht mehr
– darryn.ten
26. November 2021 um 4:48 Uhr
@darryn.ten Danke, jemand hat einen Link zu einer etwas fragwürdigen Spiegelung des ursprünglichen Inhalts hinzugefügt, und jetzt scheint sich auch das verschoben zu haben. Es gibt ähnliche “Live”-URLs, aber ich denke, es ist am besten, an dieser Stelle einfach auf die Archive.org-Version des Originalinhalts zu verweisen, und ich habe meine Antwort zu diesem Zweck bereinigt.
– nat
26. November 2021 um 21:49 Uhr
Aufbauend auf dem Mozdev-Beitrag, auf den natevw verweist, habe ich ein kleines Projekt gestartet, um HTML in Firefox, Chrome und Safari auf Leinwand zu rendern. So können Sie beispielsweise einfach Folgendes tun:
rasterizeHTML.drawHTML('<span class="color: green">This is HTML</span>'
+ '<img src="https://stackoverflow.com/questions/2732488/local_img.png"/>', canvas);
Quellcode und ein umfangreicheres Beispiel ist Hier.
tsayen
Sie können verwenden Dom-zu-Bild Bibliothek (ich bin der Betreuer).
So könnten Sie Ihr Problem angehen:
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;
});
Danke für diese Bibliothek. !! Eine kleine Änderung in Ihrem jsfiddle vorgenommen, indem Sie ein
…
in den HTML-Code eingefügt haben. Jetzt wird die Ausgabe abgeschnitten. Bitte finden Sie das neue jsfiddle https://stackoverflow.com/questions/2732488/how-can-i-convert-an-html-element-to-a-canvas-elementjsfiddle.net/2zLL7wvn Gibt es etwas, das ich falsch mache? Bitte helfen Sie. Danke,
– Müll
7. September 2016 um 13:48 Uhr
@junkle scheint an dem Rand um das h1-Tag zu liegen, kann behoben werden, indem eine Höhe festgelegt, der Rand entfernt oder der Rand in Polsterung umgewandelt wird
– xer21
20. Juli 2021 um 4:47 Uhr
Simon Sarri
Nichts dergleichen, tut mir leid.
Obwohl die Spezifikation besagt:
Eine zukünftige Version der 2D-Kontext-API bietet möglicherweise eine Möglichkeit, Fragmente von Dokumenten, die mit CSS gerendert wurden, direkt auf die Leinwand zu rendern.
Was so nah wie möglich sein kann.
Viele Leute wollen a ctx.drawArbitraryHTML/Element Art von Deal, aber so etwas ist nicht eingebaut.
Die einzige Ausnahme ist die exklusive von Mozilla drawWindow, die eine Momentaufnahme des Inhalts eines DOM-Fensters in den Zeichenbereich zeichnet. Diese Funktion ist nur für Code verfügbar, der mit Chrome-Berechtigungen (“nur lokal”) ausgeführt wird. In normalen HTML-Seiten ist es nicht erlaubt. Sie können es also zum Schreiben von Firefox-Erweiterungen wie verwenden dieser tut es aber das ist es.
Danke für diese Bibliothek. !! Eine kleine Änderung in Ihrem jsfiddle vorgenommen, indem Sie ein
…
in den HTML-Code eingefügt haben. Jetzt wird die Ausgabe abgeschnitten. Bitte finden Sie das neue jsfiddle https://stackoverflow.com/questions/2732488/how-can-i-convert-an-html-element-to-a-canvas-elementjsfiddle.net/2zLL7wvn Gibt es etwas, das ich falsch mache? Bitte helfen Sie. Danke,
– Müll
7. September 2016 um 13:48 Uhr
@junkle scheint an dem Rand um das h1-Tag zu liegen, kann behoben werden, indem eine Höhe festgelegt, der Rand entfernt oder der Rand in Polsterung umgewandelt wird
Ich bin sicher, Sie meinen es gut, aber viele Leute, wie ich, erreichen diese Fragen über spezifische Google-Abfragen, und es ist nicht hilfreich, wenn mir jemand sagt, ich solle etwas anderes tun, als das, worum ich bitte. Das Rendern von formatiertem HTML auf einer Leinwand bedeutet auch, dass ich dieses HTML in eine WebGL-Textur hochladen und formatierte Inhalte mit Transformationen und Shadern stilisiert präsentieren kann.
– Panik
19. Mai 2011 um 16:39 Uhr
Hallo @paniq, wollte nur, dass du eine alternative Technik vorstellst, die tatsächlich funktioniert und leicht zu verstehen ist. Sorry das hat dich gestört.
– Jürgen Messing
23. Mai 2011 um 9:43 Uhr
Fair genug. Stack Overflow sagt, dass ich meine Ablehnung zurücknehmen kann, wenn die ursprüngliche Antwort bearbeitet wird. Also, wenn du das tust, nehme ich es zurück. Sorry, war etwas mürrisch.
– Panik
29. Mai 2011 um 12:01 Uhr
Vielen Dank für die Einsicht, ich denke, Leute, die HTML auf Leinwand umwandeln möchten, wollen Effekte, die möglicherweise bereits in den von Ihnen geposteten Beispielen vorhanden sind. Daher freue ich mich, dass du in diesem Thread gepostet hast.
– thedrs
26. Juli 2012 um 13:20 Uhr
8693700cookie-checkWie kann ich ein HTML-Element in ein Canvas-Element umwandeln?yes