Как я могу преобразовать элемент HTML в элемент canvas?
Было бы невероятно полезно иметь возможность временно преобразовать обычный элемент в canvas
, Например, скажем, у меня есть стиль div
что я хочу перевернуть. Я хочу динамически создать холст, "визуализировать" HTMLElement
в холст, скрыть оригинальный элемент и анимировать холст.
Это можно сделать?
10 ответов
Извините, браузер не будет отображать HTML на холсте.
Это может быть потенциальная угроза безопасности, если вы можете, так как HTML может включать в себя контент (в частности, изображения и фреймы) со сторонних сайтов. Если canvas
может превратить контент HTML в изображение, а затем вы можете прочитать данные изображения, потенциально вы можете извлечь привилегированный контент из других сайтов.
Чтобы получить холст из HTML, вам нужно написать собственный HTML-рендер с нуля, используя drawImage
а также fillText
, что является потенциально огромной задачей. Есть одна такая попытка, но она немного хитрая и далека от завершения. (Он даже пытается разобрать HTML/CSS с нуля, что я считаю сумасшедшим! Было бы проще начать с реального узла DOM с примененными стилями и читать стили, используя getComputedStyle
и относительные положения его частей с помощью offsetTop
и другие.)
Есть библиотека, которая пытается сделать то, что вы говорите.
Посмотрите эти примеры и получите код
http://hertzen.com/experiments/jsfeedback/
http://html2canvas.hertzen.com/
Считывает DOM из html и рендерит его на холст, не работает на некоторых, но в целом работает.
Посмотрите этот учебник по MDN: https://developer.mozilla.org/en/HTML/Canvas/Drawing_DOM_objects_into_a_canvas
Он использует временное изображение SVG для включения содержимого HTML в качестве "внешнего элемента", а затем отображает указанное изображение SVG в элемент canvas. Однако существуют значительные ограничения на то, что вы можете включить в изображение SVG. (Подробнее см. В разделе "Безопасность".)
Вы можете использовать библиотеку 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;
});
Основываясь на посте Mozdev, который ссылается на natevw, я начал небольшой проект по визуализации HTML на canvas в Firefox, Chrome & Safari. Так, например, вы можете просто сделать:
rasterizeHTML.drawHTML('<span class="color: green">This is HTML</span>'
+ '<img src="local_img.png"/>', canvas);
Исходный код и более обширный пример здесь.
Нет такого, извини.
Хотя в спецификации говорится:
Будущая версия API 2D-контекста может предоставить способ визуализации фрагментов документов, отображаемых с использованием CSS, прямо на холст.
Который может быть так близко, как вы получите.
Многие люди хотят ctx.drawArbitraryHTML/Element
вроде сделки, но в этом нет ничего подобного.
Единственное исключение - эксклюзивный Mozilla drawWindow
, который рисует снимок содержимого окна DOM на холсте. Эта функция доступна только для кода, работающего с правами Chrome ("только локальный"). Это не разрешено на обычных страницах HTML. Таким образом, вы можете использовать его для написания расширений FireFox, как это делает, но это все.
Вы можете сэкономить преобразования, вы можете использовать переходы CSS3, чтобы перевернуть <div>
и <ol>
и любой HTML-тег, который вы хотите. Вот некоторые демонстрации с исходным кодом, объясняющие, как их увидеть и изучить: http://www.webdesignerwall.com/trends/47-amazing-css3-animation-demos/
Следующий код можно использовать в 2 режимах: в режиме 1 сохранить HTML-код в изображение, в режиме 2 - сохранить HTML-код на холсте.
этот код работает с библиотекой: https://github.com/tsayen/dom-to-image
* "id_div" - это идентификатор элемента HTML, который вы хотите преобразовать.
** "canvas_out" - это идентификатор div, который будет содержать холст, поэтому попробуйте этот код.:
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>
Прокомментируйте, если это работает. Comenten si les sirvio:)
Самым простым решением для анимации элементов DOM является использование CSS-переходов / анимаций, но я думаю, что вы уже это знаете и пытаетесь использовать canvas для выполнения вещей, которые CSS не позволяет вам делать. Как насчет пользовательских фильтров CSS? Вы можете преобразовать свои элементы любым мыслимым способом, если вы знаете, как писать шейдеры. Некоторые другие ссылки и не забудьте проверить лабораторию фильтров CSS.
Примечание. Как вы, вероятно, можете себе представить, поддержка браузера плохая.
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();
}
}