Html2canvas: Capture SVG

Criado em 26 abr. 2012  ·  64Comentários  ·  Fonte: niklasvh/html2canvas

Olá,

O html2canvas suporta a captura de SVG, se sim, como fazer isso? Você poderia dar um exemplo?

O exemplo em tests \ images não capturou SVG.

Por favor ajude. Muito obrigado.

Question

Comentários muito úteis

Oi pessoal,
Eu resolvo esse problema (perdi o svg com o firefox) mudando um pouco o código-fonte.
Em primeiro lugar, o elemento SVG deve ter os atributos de altura e largura, não importando com pixels ou não.
então você deve alterar o código-fonte de:
self.image.src = " dados: imagem / svg + xml ," + (novo XMLSerializer ()). serializeToString (nó);
para:
self.image.src = " data: image / svg + xml ," + encodeURIComponent ((new XMLSerializer ()). serializeToString (node));

então aproveite.

Todos 64 comentários

Não, não tem. Não é uma falha na biblioteca, mas um bug na maioria dos navegadores (última versão estável do Firefox, versão 12, corrigiu esse problema e é o único em que funciona como o esperado afaik). O problema é que qualquer imagem SVG mancha a tela, tornando-a ilegível. Por padrão, o html2canvas ignora o conteúdo que mancha a imagem, pois queremos manter a tela legível (por exemplo, se você quiser usar toDataUrl ).

Se, entretanto, você não se importa que as imagens SVG manchem a tela, você pode definir a opção allowTaint para true e os SVGs devem ser renderizados corretamente para navegadores que permitem SVG embutido.

Também gostaria de salientar que se a renderização de SVG funcionasse corretamente em todos os navegadores, essa biblioteca se tornaria quase obsoleta, pois o SVG pode ser usado para renderizar HTML. Já comprometi algum código que acelera a renderização do canvas significativamente em navegadores onde a renderização SVG funciona (ou seja, FF12), além de permitir o suporte para todas as propriedades CSS que o navegador suporta. Para obter informações, dê uma olhada em https://github.com/niklasvh/html2canvas/blob/master/src/Parse.js#L1227

Olá,
Muito obrigado pela sua resposta rápida.
Tentei conforme suas sugestões: defina allowTaint como true conforme abaixo (modifique test.js):

setTimeout (function () {

        $(h2cSelector).html2canvas($.extend({
            flashcanvas: "../external/flashcanvas.min.js",
            logging: true,
            profile: true,
            useCORS: true,
            allowTaint: true
        }, h2cOptions));
    }, 100);

É renderizado SVG com sucesso no exemplo images.html.

Mas no caso do SVG ser mais complicado, ele não é renderizado corretamente no navegador cruzado. Por exemplo: Eu gostaria de capturar o gráfico (http://www.highcharts.com/demo/), no Chrome: ele apenas captura o eixo xey do gráfico quando o gráfico é renderizado como SVG embutido, no gráfico caso renderizar como img com fonte do arquivo svg externo, não captura nada.
Ao contrário do Chrome, no Firefox, ele não captura nada quando o gráfico é renderizado como SVG embutido, mas pode capturar o gráfico com sucesso quando o gráfico é uma imagem de um arquivo svg externo. O pior é no IE9, nada é capturado.

Tem alguma ideia para resolver este problema?

Usar como imagem deve funcionar para FF / Chrome. O que você pode tentar é se uma renderização de tela simples usando drawImage funciona com o SVG.

1 para isso. Tenho o mesmo caso de uso de babyhero, preciso fazer uma captura de tela de gráficos SVG de highcharts para uma ferramenta de relatório. Pode ser possível pegar todos os SVGs de highcharts individualmente, mas ele é renderizado em uma visualização com outras informações para as quais gostaríamos de ter o recurso "Salvar na captura de tela".

@ babyhero184 Consegui contornar essa limitação no html2canvas usando canvg (http://code.google.com/p/canvg/) para converter SVGs em PNGs rapidamente, ocultando os elementos SVG e mostrando o PNG. Então eu tirei uma captura de tela em tempo real com html2canvas e, em seguida, escondi o PNG e mostrei o SVG de highcharts novamente. É um processo indireto (SVG -> canvas -> PNG -> canvas -> PNG), mas funciona para minhas necessidades.

@joeyrobert Também estou enfrentando o mesmo problema com highcharts e html2canvas. Será uma grande ajuda se você puder compartilhar a essência do seu código.
Desde já, obrigado.

@joeyrobert @ Jagdeep1 outra opção é usar Fabric.js para renderizar SVG na tela e, em seguida, recuperar sua imagem.

+1

+1

+1

alguma solução para este problema?

@majuansari _SVG_ para _Canvas_ e _Canvas_ para _image_ funcionam no firefox, mas no Chrome há uma trava de segurança.

Eu estava usando jQuery para capturar elementos de gráfico e descobri que o Highcharts SVG não foi analisado corretamente quando o fez. Se alguém estiver passando um seletor jQuery de um gráfico, ele pode não conter o SVG.

@mbritton tente http://code.google.com/p/canvg/ (ForeignObject não funciona)

Sim, essa foi a minha solução.

Resolvi esse problema substituindo elementos svg por elementos canvas gerados por canvg durante a captura.
Aqui está meu código.

// targetElem is a jquery obj
function take (targetElem) {
    var nodesToRecover = [];
    var nodesToRemove = [];

    var svgElem = targetElem.find('svg');

    svgElem.each(function(index, node) {
        var parentNode = node.parentNode;
        var svg = parentNode.innerHTML;

        var canvas = document.createElement('canvas');

        canvg(canvas, svg);

        nodesToRecover.push({
            parent: parentNode,
            child: node
        });
        parentNode.removeChild(node);

        nodesToRemove.push({
            parent: parentNode,
            child: canvas
        });

        parentNode.appendChild(canvas);
    });

    html2canvas(targetElem, {
        onrendered: function(canvas) {
            var ctx = canvas.getContext('2d');
            ctx.webkitImageSmoothingEnabled = false;
            ctx.mozImageSmoothingEnabled = false;
            ctx.imageSmoothingEnabled = false;

            canvas.toBlob(function(blob) {
                nodesToRemove.forEach(function(pair) {
                    pair.parent.removeChild(pair.child);
                });

                nodesToRecover.forEach(function(pair) {
                    pair.parent.appendChild(pair.child);
                });
                saveAs(blob, 'screenshot_'+ moment().format('YYYYMMDD_HHmmss')+'.png');
            });
        }
    });
}

Apenas uma nota rápida:
Tenho certeza de que canvg está funcionando bem, mas se você simplesmente deseja converter SVG em canvas, pode usar a técnica simples descrita aqui que carrega o svg em uma imagem e, em seguida, obtém o conteúdo da imagem como dataURL.

var image = new Image();
var xml = '<svg xmlns=....></svg>';
image.src = 'data:image/svg+xml,' + escape(xml); 
document.getElementById('container').appendChild(image);
image.onload = function() {
    image.onload = function() {};
    var canvas = document.createElement('canvas');
    canvas.width = image.width;
    canvas.height = image.height;
    var context = canvas.getContext('2d');
    context.drawImage(image, 0, 0);
    image.src = canvas.toDataURL();
}

@steren : Embora funcione muito bem no Chrome, existe uma solução alternativa para o Firefox, que produz um NS_ERROR_NOT_AVAILABLE na linha context.drawImage (imagem, 0, 0) - aparentemente um bug conhecido - ou IE 11 onde um SecurityError aparece na tela. toDataURL () apesar de a imagem estar no mesmo domínio? Não consegui fazê-lo funcionar em outros navegadores além do Chrome ...

@gifarangw seu código funciona bem com highcharts. Obrigado pelo seu código maravilhoso. : +1: A única coisa que removi foi a parte canvas.toBlob.

@steren obrigado pela sua solução, funciona bem (testado no Chrome e Firefox mais recentes) e não precisa de uma biblioteca adicional, o que é bom. Fiz algumas alterações e combinei com o código de @gifarangw e obtive:

    function take(targetElem) {
        // First render all SVGs to canvases
        var elements = targetElem.find('svg').map(function() {
            var svg = $(this);
            var canvas = $('<canvas></canvas>');
            svg.replaceWith(canvas);

            // Get the raw SVG string and curate it
            var content = svg.wrap('<p></p>').parent().html();
            content = content.replace(/xlink:title="hide\/show"/g, "");
            content = encodeURIComponent(content);
            svg.unwrap();

            // Create an image from the svg
            var image = new Image();
            image.src = 'data:image/svg+xml,' + content;
            image.onload = function() {
                canvas[0].width = image.width;
                canvas[0].height = image.height;

                // Render the image to the canvas
                var context = canvas[0].getContext('2d');
                context.drawImage(image, 0, 0);
            };
            return {
                svg: svg,
                canvas: canvas
            };
        });
        targetElem.imagesLoaded(function() {
            // At this point the container has no SVG, it only has HTML and Canvases.
            html2canvas(targetElem[0], {
                onrendered: function(canvas) {
                    // Put the SVGs back in place
                    elements.each(function() {
                        this.canvas.replaceWith(this.svg);
                    });

                    // Do something with the canvas, for example put it at the bottom
                 $(canvas).appendTo('body');
                }
            })
        })
    }

(usa https://github.com/desandro/imagesloaded)

Olá a todos, só para dizer que a solução @Remiremi funcionou muito bem para mim! Tenho uma página com muitos gráficos criados com HighStocks em svg e essa solução funcionou muito bem! Muito bem, galera!

@Remiremi @fbotti , Por algum motivo não entro no img.onLoad, portanto, os gráficos desaparecem (não sendo substituídos pelo canvas)

Estou trabalhando com amcharts. Qualquer ideia?

@guypaskar, seu svg pode precisar de mais curadoria. Você pode adicionar $(image).appendTo('body'); ao código antes de definir image.onload , então no Firefox você verá um ícone para a imagem inválida, você pode clicar com o botão direito> visualizar imagem e ver o erro.

Eu tentei rapidamente um amcharts svg e tive que adicionar as propriedades xmlns="http://www.w3.org/2000/svg" width="1400" height="500" à tag svg para fazê-la funcionar. (A altura e a largura foram especificadas como propriedades css, mas por algum motivo não foram selecionadas.)

Eu encontrei uma solução simples.

Certifique-se de que sua imagem SVG tenha largura e altura.

Caso contrário, não há argumentos suficientes porque um svg não pode ser medido como uma imagem.

Alguém pode recapitular sobre este assunto? O problema original foi resolvido? Parece que certos problemas do navegador que podem ter causado a maioria dos problemas mencionados aqui foram corrigidos desde 2012. De acordo com alguns comentários aqui, o uso de outras bibliotecas, como canvg, também não é mais necessário?

Para os problemas restantes, eles seriam cobertos pelo nº 197 e / ou nº 267? Este pode ser fechado?

Ainda é um problema com pelo menos alguns navegadores

0,5 adiciona suporte para SVG's

Qualquer visualização quando 0,5 sairá @niklasvh ?

@IvoPereira Você pode acompanhar o status de 0,5 no # 421

@niklasvh Tenho a versão 0.5 e o SVG ainda não renderiza. Existe um exemplo de como fazer isso? (É um SVG embutido)

@nikolang você incluiu html2canvas.js e html2canvas.svg.js ? Em caso afirmativo, você pode fornecer um jsFiddle ou jsbin para demonstrar seu problema específico?

Eu tenho isso funcionando. O problema é que o SVG não foi totalmente renderizado quando fiz o html2canvas.

Mas parece que ainda existem alguns problemas com a renderização. Por exemplo http://d3pie.org

É assim que deveria ser:

screen

Isso é o que parece depois de html2canvas:

canvas

Uau, isso é muito assustador. Para ficar mais fácil de controlar, você pode abrir um problema separado com as mesmas capturas de tela e um link para apenas um jsFiddle com a demonstração? Isso está se distanciando muito da questão original, que foi encerrada há muito tempo. Obrigado por relatar isso!

Eu adoraria fazer isso, mas não sei como incluir o novo html2canvas no jsfiddle. Existe algum link externo que eu possa usar?

Obrigado. E a versão SVG?

Oi,

SVGs são renderizados do meu lado, mas aparecem em preto, conforme relatado por alguém abaixo. Existe uma maneira de contar a propriedade "fill" dos elementos svg?

@brainra , estou usando algo assim para deixar o preenchimento branco:

// Create dummy canvas to get a white background
var destinationCanvas = document.createElement("canvas");
destinationCanvas.width = canvas.width;
destinationCanvas.height = canvas.height;

var destCtx = destinationCanvas.getContext('2d');

//create a rectangle with the desired color
destCtx.fillStyle = "#FFFFFF";
destCtx.fillRect(0,0,canvas.width,canvas.height);

//draw the original canvas onto the destination canvas
destCtx.drawImage(canvas, 0, 0);

var img = destinationCanvas.toDataURL("image/png");

Falha ao executar 'drawImage' em 'CanvasRenderingContext2D': O HTMLImageElement fornecido está no estado 'quebrado'. "

Estou recebendo este erro quando há elemento SVG em HTML.
Além disso, configurei allowTaint como true. Alguém por favor pode me ajudar?

Acho que isso deve ser reaberto - os elementos SVG estão sendo renderizados corretamente em todos os navegadores, exceto no Firefox.

NS_ERROR_NOT_AVAILABLE: este é um bug do Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=700533 (AFAICT) há uma página de teste que destaca o problema ( link do bug)

Uma solução alternativa / correção seria muito apreciada. Ou talvez alguém pudesse cutucar alguém @mozilla para consertar isso :)

Tentei usar o angular, mas acabei com uma tela manchada. Acho que preciso do SVG bruto.

<img svg-2-canvas-src="/assets/your.svg"/>

angular.module('APP')
    .directive('svg2CanvasSrc', function() {
        return {
            restrict: 'A',
            scope: false,
            link: function($scope, $element, $attrs) {

                var svgSrc = $attrs['svg2CanvasSrc'];

                var image = new Image();

                image.onload = function() {
                    image.onload = function() {};
                    var canvas = document.createElement('canvas');
                    canvas.width = image.width;
                    canvas.height = image.height;
                    var context = canvas.getContext('2d');
                    context.drawImage(image, 0, 0);
                    $element[0].src = canvas.toDataURL();
                };

                image.src = svgSrc;
            }
        };
    });

@remiremi eu usei seu código, mas o resultado é o mesmo, svg está faltando ..
original - https://s29.postimg.org/5lkprhx93/with_SVG.png
resultado - https://s23.postimg.org/j1otj2por/without_SVG.png

@remiremi ... qual é o nome do plugin que tenho anexado ao usar este script

Basicamente, definir uma largura / altura explícita no SVG antes de chamar html2canvas corrige a maioria dos casos para mim.
O que eu faço é percorrer os vários elementos SVG de interesse, obter a largura / altura calculada do navegador usando .getBoundingClientRect () e definir a propriedade largura e altura no elemento. Observei que quando os SVGs têm porcentagem e largura / altura semelhantes definidas, não não renderizar, mas com pixels, Booyah

Ainda tendo problemas para renderizar span e div de várias linhas

Oi pessoal,
Eu resolvo esse problema (perdi o svg com o firefox) mudando um pouco o código-fonte.
Em primeiro lugar, o elemento SVG deve ter os atributos de altura e largura, não importando com pixels ou não.
então você deve alterar o código-fonte de:
self.image.src = " dados: imagem / svg + xml ," + (novo XMLSerializer ()). serializeToString (nó);
para:
self.image.src = " data: image / svg + xml ," + encodeURIComponent ((new XMLSerializer ()). serializeToString (node));

então aproveite.

Alguém tem uma ideia de como eu chamaria html2canvas em um elemento SVG no DOM?

Um exemplo seria ótimo!

+1 ainda é um problema para capturar a captura de tela do elemento SVG no firefox.

{
  profile: true,
  allowTaint: false,
  onrendered: function() {
    //...done()
  }
}

Ei, consegui resolver esse problema usando esta solução (sem jQuery):
Solução

deixe targetElem =document.getElementById ('body');
let nodesToRecover = [];
let nodesToRemove = [];

    let svgElem = targetElem.querySelector('svg')

    let parentNode = svgElem.parentNode;
        // let svg = parentNode.innerHTML;
        let svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" id=\"svg-annotations\" style=\"opacity: 1;\" _ngcontent-c7=\"\">\n\t\t\t<defs><marker id=\"arrow-start\" refY=\"4.5\" markerWidth=\"9.9\" markerHeight=\"9\" orient=\"auto\"><path fill=\"black\" d=\"M 9.9 0 L 9.9 9 L 0 4.5 Z\" /></marker><marker id=\"arrow-end\" refX=\"9.9\" refY=\"4.5\" markerWidth=\"9.9\" markerHeight=\"9\" orient=\"auto\"><path fill=\"black\" d=\"M 0 0 L 0 9 L 9.9 4.5 Z\" /></marker></defs><g class=\"annotation-group\" id=\"measurement-36122\" style=\"opacity: 1;\"><g class=\"annotations\"><g class=\"annotation callout elbow editable \" transform=\"translate(758.541 408.978)\"><g class=\"annotation-connector\"><path class=\"connector\" fill=\"none\" stroke=\"black\" d=\"M 0 0 L 137 137 L 162 137\" /></g><g class=\"annotation-note\" transform=\"translate(162 137)\"><g class=\"annotation-note-content\" transform=\"translate(0 3)\"><rect class=\"annotation-note-bg\" fill=\"white\" fill-opacity=\"0\" x=\"0\" width=\"104.79\" height=\"41.36\" /><text class=\"annotation-note-label\" fill=\"black\" y=\"41.36\" dx=\"0\"><tspan x=\"0\" dy=\"0.8em\" /></text><text class=\"annotation-note-title\" font-weight=\"bold\" fill=\"black\"><tspan x=\"0\" dy=\"0.8em\">Face</tspan><tspan x=\"0\" dy=\"1.2em\">:5453831.5mm²</tspan></text></g><path class=\"note-line\" stroke=\"black\" d=\"M 0 0 L 104.79 0\" /><circle class=\"handle \" cursor=\"move\" fill=\"grey\" fill-opacity=\"0.1\" stroke=\"grey\" stroke-dasharray=\"5\" cx=\"0\" cy=\"0\" r=\"10\" /></g></g></g></g><g class=\"annotation-group\" id=\"measurement-59622\" style=\"opacity: 1;\"><g class=\"annotations\"><g class=\"annotation callout elbow editable \" transform=\"translate(889.656 387.507)\"><g class=\"annotation-connector\"><path class=\"connector\" fill=\"none\" stroke=\"black\" d=\"M 0 0 L 137 137 L 162 137\" /></g><g class=\"annotation-note\" transform=\"translate(162 137)\"><g class=\"annotation-note-content\" transform=\"translate(0 3)\"><rect class=\"annotation-note-bg\" fill=\"white\" fill-opacity=\"0\" x=\"0\" width=\"104.79\" height=\"41.36\" /><text class=\"annotation-note-label\" fill=\"black\" y=\"41.36\" dx=\"0\"><tspan x=\"0\" dy=\"0.8em\" /></text><text class=\"annotation-note-title\" font-weight=\"bold\" fill=\"black\"><tspan x=\"0\" dy=\"0.8em\">Face</tspan><tspan x=\"0\" dy=\"1.2em\">:5453831.5mm²</tspan></text></g><path class=\"note-line\" stroke=\"black\" d=\"M 0 0 L 104.79 0\" /><circle class=\"handle \" cursor=\"move\" fill=\"grey\" fill-opacity=\"0.1\" stroke=\"grey\" stroke-dasharray=\"5\" cx=\"0\" cy=\"0\" r=\"10\" /></g></g></g></g></svg>";

        this.canvas = document.createElement('canvas');
        this.canvas.setAttribute('id', '_canvas');

        canvg(this.canvas, svg, {renderCallback: function(){
            console.log(this);
        }});

        nodesToRecover.push({
            parent: parentNode,
            child: svgElem
        });
        parentNode.removeChild(svgElem);

        nodesToRemove.push({
            parent: parentNode,
            child: this.canvas
        });

        parentNode.appendChild(this.canvas);
        let data = this.canvas.toDataURL('image/png', 0.5);
        console.log(data);

Estou fazendo isso, mas consigo apenas a imagem em branco no IE11. Mas, eu posso ver a tela na página da web. Alguém pode me ajudar o que estou fazendo de errado aqui?

Olá. Eu tenho um problema de renderização de svg quando esta tem <image> tag.
barchart (24)

Amostra de SVG

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" height="200" width="200"/>
</svg>

Amostra em jsfiddle http://jsfiddle.net/maestro888/fmjywksq/

Eu encontrei uma solução simples.

Certifique-se de que sua imagem SVG tenha largura e altura.

Caso contrário, não há argumentos suficientes porque um svg não pode ser medido como uma imagem.

Isso é verdade, mas não para o IE11, infelizmente ...

Que bom que você resolveu.
Apenas verifiquei seu JS Fiddle e ele está exibindo a imagem.

Saudações,

Bernard TA Baker

Na quarta-feira, 27 de março de 2019 às 16h34 Alessandro Candini [email protected]
escrevi:

Eu encontrei uma solução simples.

Certifique-se de que sua imagem SVG tenha largura e altura.

Caso contrário, não há argumentos suficientes porque um svg não pode ser medido
como uma imagem pode.

Isso é verdade, mas não para o IE11, infelizmente ...

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/niklasvh/html2canvas/issues/95#issuecomment-477242192 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AM7ZzLPsl0WJS7gGI9npSsRxR33FCnN9ks5va52bgaJpZM4AD-Sb
.

Eu encontrei uma solução com canvg , relatado aqui sobre estouro de pilha : funciona perfeitamente no IE11!

Meu snippet reelaborado, removendo a dependência do jQuery:

let svgIcons = document.querySelectorAll('.svg-icon');

for (let i = 0; i < svgIcons.length; ++i) {
  let curSvg = svgIcons[i];
  let canvas;
  let xml;

  // Size and color needed for every browser
  curSvg.setAttribute('width', curSvg.parentNode.offsetWidth);
  curSvg.setAttribute('height', curSvg.parentNode.offsetHeight);
  curSvg.setAttribute('style', 'fill: blue');

  canvas = document.createElement('canvas');
  canvas.className = 'screenShotTempCanvas';
  xml = new XMLSerializer().serializeToString(curSvg);
  canvg(canvas, xml);
  curSvg.parentNode.insertBefore(canvas, curSvg.nextSibling);
  curSvg.style.display = 'none';
 }

Ótimo

Em quinta-feira, 28 de março de 2019, 08:49 Alessandro Candini, notificaçõ[email protected]
escrevi:

Encontrei uma solução com canvg https://github.com/canvg/canvg ,
relatado aqui no estouro de pilha
https://stackoverflow.com/questions/34042440/using-html2canvas-to-render-a-highcharts-chart-to-pdf-doesnt-work-on-ie-and-fir :
funciona perfeitamente no IE11!

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/niklasvh/html2canvas/issues/95#issuecomment-477503221 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AM7ZzKNy1GOgQU9TVv7PGCi4fJvYSxDVks5vbIIOgaJpZM4AD-Sb
.

Olá @niklasvh Bom ver sua biblioteca javascript html2canvas, é uma biblioteca incrível, mas ainda estou enfrentando o mesmo problema para renderizar o svg na criação de tela usando npm versão "1.0.0-alpha.12
"bem como a versão" 1.0.0-rc.1 "também em nosso aplicativo anguar6, de acordo com sua resposta da lista de problemas, O problema virá svg não contém a altura e largura, mas no meu caso meu Svg tem 100% de altura e largura e div aninhado contém a tag svg também e a tela existente aninhada também, posso exportar minha página como uma imagem png, mas a imagem contém apenas os ícones svg travados e a tela existente também não é renderizada. E mais uma coisa quando a exportação for concluída minha outra página svg all está aparecendo como imagens travadas. para sua referência, anexei minha captura de tela aqui, por favor, dê uma olhada uma vez e deixe-me saber, obrigado.
html2canvas (this.screen.nativeElement, {useCORS: true}). then (canvas => {
this.canvas.nativeElement.src = canvas.toDataURL ('image / png');
this.downloadLink.nativeElement.href = canvas.toDataURL ('image / png');
this.downloadLink.nativeElement.download = 'screenshot.png';
this.downloadLink.nativeElement.click ();
});

html2canvas_orginal_Before export
html2canvas_orginal_after export
html2canvas_exported image

testpdf (1) .pdf
Oi,
Estou obtendo o eixo, mas o resto da área do gráfico está preto. Alguma sugestão

Olá @niklasvh Bom ver sua biblioteca javascript html2canvas, é uma biblioteca incrível, mas ainda estou enfrentando o mesmo problema para renderizar o svg na criação de tela usando npm versão "1.0.0-alpha.12
"bem como a versão" 1.0.0-rc.1 "também em nosso aplicativo anguar6, de acordo com sua resposta da lista de problemas, O problema virá svg não contém a altura e largura, mas no meu caso meu Svg tem 100% de altura e largura e div aninhado contém a tag svg também e a tela existente aninhada também, posso exportar minha página como uma imagem png, mas a imagem contém apenas os ícones svg travados e a tela existente também não é renderizada. E mais uma coisa quando a exportação for concluída minha outra página svg all está aparecendo como imagens travadas. para sua referência, anexei minha captura de tela aqui, por favor, dê uma olhada uma vez e deixe-me saber, obrigado.
html2canvas (this.screen.nativeElement, {useCORS: true}). then (canvas => {
this.canvas.nativeElement.src = canvas.toDataURL ('image / png');
this.downloadLink.nativeElement.href = canvas.toDataURL ('image / png');
this.downloadLink.nativeElement.download = 'screenshot.png';
this.downloadLink.nativeElement.click ();
});

html2canvas_orginal_Before export
html2canvas_orginal_after export
html2canvas_exported image

o mesmo problema, Erro ao encontrar o SVG no documento clonado

Antes de usar o html2canvas, estou definindo temporariamente a altura e a largura dos SVGs. Desta forma, consigo capturar o SVG.

var selectedItem = document.querySelector (". chartWrapper");
var svgElements = selectedItem.querySelectorAll ('svg');
para (deixe i = 0; i <svgElements.length; i ++) {
selectedItem.getElementsByTagName ("svg") [i] .style.height = document.getElementsByTagName ("svg") [i] .getBoundingClientRect (). height;
selectedItem.getElementsByTagName ("svg") [i] .style.width = document.getElementsByTagName ("svg") [i] .getBoundingClientRect (). width;
}
html2canvas (selectedItem, {backgroundColor: '# 000', allowTaint: true}). then (canvas => {
var myImage = canvas.toDataURL ("imagem / png"). replace ("imagem / png", "imagem / fluxo de octeto");
window.location.href = myImage;
})
para (deixe i = 0; i <svgCount; i ++) {
selectedItem.getElementsByTagName ("svg") [i] .style.height = '100%';
selectedItem.getElementsByTagName ("svg") [i] .style.width = '100%';
}

// use html2canvas in react project when i need a screenshot for the svg
/**
 * svg to canvas
 * <strong i="5">@param</strong> targetElem
 * <strong i="6">@return</strong> {Promise<[]>} // return svg elements
 */
async function svgToCanvas(targetElem) {
  let nodesToRecover = [], nodesToRemove = [], svgElems = targetElem.querySelectorAll('svg');

  for (let i = 0; i < svgElems.length; i++) {
    let node = svgElems[i], parentNode = node.parentNode, svg = parentNode.innerHTML,
      canvas = document.createElement('canvas'),
      ctx = canvas.getContext('2d');
    canvas.setAttribute('data-cover', 'svg');
    const v = await Canvg.from(ctx, svg);
    v.start();
    // record svg elements
    nodesToRecover.push({
      parent: parentNode,
      child: node
    });
    parentNode.removeChild(node);
    //  record canvas elements
    nodesToRemove.push({
      parent: parentNode,
      child: canvas
    });

    parentNode.appendChild(canvas);
  }
  return nodesToRecover;
}

/**
 * recover canvas to svg
 * <strong i="7">@param</strong> targetElem
 * <strong i="8">@param</strong> svgElems // need to recover svg elements
 * <strong i="9">@return</strong> *
 */
function recoverCanvasToSvg(targetElem, svgElems) {
  let canvasElems = targetElem.querySelectorAll("canvas[data-cover='svg']");
  if(!targetElem){
    throw new Error('must have targetElem param')
  }
  if(!isArray(svgElems) && svgElems.length !== canvasElems.length) {
    throw new Error('svgElems must be an Array, and it`s length equal to canvasElems`s length')
  }
  for(let i = 0; i < canvasElems.length; i++){
    let node = canvasElems[i], parentNode = node.parentNode;
    parentNode.removeChild(node);
    parentNode.appendChild(svgElems[i]?.child);
  }
}
Esta página foi útil?
0 / 5 - 0 avaliações