Как преобразовать элемент HTML в элемент canvas?

Было бы невероятно полезно временно преобразовать обычный элемент в canvas. Например, скажем, у меня есть стиль div, который я хочу перевернуть. Я хочу динамически создавать холст, "визуализировать" HTMLElement в холсте, скрывать исходный элемент и анимировать холст.

Можно ли это сделать?

Ответ 1

К сожалению, браузер не будет отображать HTML в холст.

Это может быть потенциальным риском для безопасности, если вы можете, так как HTML может включать контент (в частности, изображения и фреймы) с сторонних сайтов. Если canvas может превратить содержимое HTML в изображение, а затем вы читаете данные изображения, вы можете потенциально извлечь привилегированный контент с других сайтов.

Чтобы получить холст из HTML, вам придется писать свой собственный рендеринг HTML с нуля, используя drawImage и fillText, что является потенциально огромной задачей. Там одна такая попытка, но это немного изворотливая и далеко от полной. (Он даже пытается проанализировать HTML/CSS с нуля, что, я думаю, сходит с ума! Легче начать с реального узла DOM с примененных стилей и прочитать стиль с использованием getComputedStyle и относительное положение его частей с помощью offsetTop и другие.)

Ответ 2

Существует библиотека, которая пытается делать то, что вы говорите.

Смотрите примеры и получите код

http://hertzen.com/experiments/jsfeedback/

http://html2canvas.hertzen.com/

Читает DOM, из html и выводит его на холст, не работает на некоторых, но в целом работает.

Ответ 3

Основываясь на записи Mozdev, которая ссылается на natevw, я запустил небольшой проект для рендеринга HTML на холст в Firefox, Chrome и Safari. Так, например, вы можете просто сделать:

rasterizeHTML.drawHTML('<span class="color: green">This is HTML</span>' 
                     + '<img src="local_img.png"/>', canvas);

Исходный код и более обширный пример здесь.

Ответ 4

Посмотрите это руководство по MDN: https://developer.mozilla.org/en/HTML/Canvas/Drawing_DOM_objects_into_a_canvas (в архиве)

Альтернативная ссылка (2019): https://reference.codeproject.com/book/dom/canvas_api/drawing_dom_objects_into_a_canvas

Он использует временное изображение SVG для включения содержимого HTML в качестве "внешнего элемента", а затем визуализирует упомянутое изображение SVG в элемент холста. Однако существуют значительные ограничения на то, что вы можете включить в изображение SVG. (Подробнее см. в разделе "Безопасность".)

Ответ 5

Вы можете использовать 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;
});

И вот jsfiddle

Ответ 6

Нет такой вещи, извините.

Хотя spec указывает:

Будущая версия 2D-контекстного API может предоставить способ визуализации фрагментов документов, созданных с использованием CSS, прямо на холст.

Что может быть как можно ближе.

Многие люди хотят иметь дело с ctx.drawArbitraryHTML/Element, но там ничего не построено.

Единственным исключением является Mozilla exclusive drawWindow, который рисует моментальный снимок содержимого окна DOM в холсте. Эта функция доступна только для кода, работающего с привилегиями Chrome ( "только для локальных" ). Это запрещено в обычных HTML-страницах. Таким образом, вы можете использовать его для написания расширений FireFox, таких как который он делает, но что он.

Ответ 7

Вы можете избавить себя от преобразований, вы можете использовать CSS3 Transitions для переключения <div> и <ol> и любого HTML-тега, который вы хотите. Вот несколько демонстраций с исходным кодом, которые объясняют, чтобы посмотреть и узнать: http://www.webdesignerwall.com/trends/47-amazing-css3-animation-demos/

Ответ 8

Самое простое решение для анимирования элементов DOM - это использование переходов/анимаций CSS, но я думаю, что вы уже знаете это, и вы пытаетесь использовать canvas для создания CSS, который не позволяет вам делать. Что относительно CSS пользовательских фильтров? вы можете трансформировать свои элементы любым мыслимым способом, если вы знаете, как писать шейдеры. Некоторые другие ссылка и не забудьте проверить фильтр фильтров CSS.
Примечание. Как вы, вероятно, можете предположить, что поддержка браузера плохая.

Ответ 9

следующий код можно использовать в двух режимах, режим 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:)

Ответ 10

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