Html2canvas: Problema para gerar a imagem do mapa (Google Maps)

Criado em 6 mar. 2014  ·  51Comentários  ·  Fonte: niklasvh/html2canvas

Oi, pessoal.
Preciso gerar uma imagem do meu diálogo:

1

Usando html2canvas, mas a criação de imagem não mostra o mapa:

2

Meu código:

            function imagem()
            {
                var html2obj = html2canvas($('#dialogPrint'));
                var queue  = html2obj.parse();
                var canvas = html2obj.render(queue);
                var img = canvas.toDataURL();
                window.open(img);
            };

Preciso de ajuda, por favor.
obrigado

Needs More Information

Comentários muito úteis

Parece que, na nova versão do google maps, a transformação é aplicada a diferentes div. Usar a solução de @GCorbel , mas com este seletor (".gm-style> div: first> div: first> div: last> div") parece funcionar. Embora eu ainda não tenha testado completamente.

Todos 51 comentários

O problema é que o google maps usa a matriz de transformação CSS3, que não é totalmente implementada no html2canvas.

como eu faço?

Imagens do Google Maps (imagens em servidor externo)?

Use proxy: https://github.com/niklasvh/html2canvas#how -does-it-work

brcontainer: Eu acho que é ilegal (acessar blocos de mapas diretamente de outro computador / proxy /). A única maneira é usar CORS.

O proxy

O proxy faz um download do servidor externo e o html2canvas carrega a imagem somente após a conclusão do download.

Leia esta http://en.wikipedia.org/wiki/Same_origin_policy para você entender o assunto.

como faço para usar este proxy?

O link que você passou todos os links para o uso de proxy (em linguagens php, C # (asp.net), python e VB (asp classic)).

Talvez você não tenha notado os links para os proxies, então vou te dar aqui:
https://github.com/niklasvh/html2canvas/wiki/Proxies

Ao usar uma nova biblioteca é sempre bom ler todo o README.

@brcontainer Eu sei o que esse proxy faz - quando o cliente deseja fazer uma captura de tela, o SERVER baixa todas as imagens para a pasta local e o cliente as carrega. Mas isso está errado - porque o Google não permite o uso direto de seus servidores de til - e do ponto de vista deles, alguém está baixando um monte de blocos para o servidor sem visualizar a página da web ...

estou usando Java.
você tem um exemplo para usar o proxy?

@brcontainer E como mencionei, há realmente um problema com as transformações CSS3, porque os googlemaps em execução no Google Chrome as usam, portanto, o mapa não pode ser filtrado com a implementação atual. Acredite em mim, tive esse problema no projeto que escrevi ...

@bkralik Então, como posso fazer?
você tem algum exemplo?

Também programo em java (já criei proxies em PHP, C # e VB), mas não estou a tempo de criar um proxy em Java, talvez consiga fazer no domingo.

Sua aplicação é JSP ou "Java Desktop"?

@brcontainer É uma aplicação web, usando JSF, Primefaces, Javascript e Java

@DanielSBelo Framework JSF que nunca usei,

[editado]
Sobre o suporte a transformações css, leia: https://github.com/niklasvh/html2canvas#contributing

@DanielSBelo você achou uma boa solução para isso? Estou tendo o mesmo problema.

Salvar um mapa como tela funciona bem no Firefox, mas falha ao salvar o mapa no Chrome. Não acho que esteja diretamente relacionado à transformação, mas mais provavelmente à maneira como o Chrome lida com CORs. Estou totalmente preso tentando encontrar uma resposta, no entanto.

@TGOlson É realmente um problema com as transformações CSS3, porque a versão atual do html2canvas é capaz de renderizar apenas "um nível" de transformação - não os empilha.
Você pode verificar se o problema está nas transformações simplesmente brincando com o Google Maps - normalmente, uma captura de tela como esta é fornecida:
map_2014-08-10_10-44-02
(No css, todo o mapa é posicionado corretamente, mas depois de desabilitar o css3, isso acontece)
A única solução é implementar a pilha de transformações css3 inteira. Não sei, se está em andamento por Niklas, mas alguém deveria fazer :-)

inscrevendo

Também estou tendo o mesmo problema - apenas no Chrome. Estou usando html2canvas-proxy-php. Outros navegadores funcionam bem. Algumas partes do mapa estão faltando .. parece estar relacionado ao redimensionamento do mapa, adição / remoção de superposições, etc.

Para sua informação - se você precisa obter alguma funcionalidade de captura de mapa para funcionar rapidamente, você sempre pode usar o Google Streetview ou a API de mapas estáticos. Basicamente, reconstrua o que o usuário atual está olhando no mapa ( map.getPov , etc.) e obtenha a imagem estática do google.

Não acho que essa abordagem funcione com sobreposições

Acabei de me deparar com esse problema. Se não me engano, esta questão stackoverflow apresenta esse problema e eu ofereci uma solução alternativa lendo as transformações css3 e aplicando-as como posições CSS normais.

var transform=$(".gm-style>div:first>div").css("transform")
var comp=transform.split(",") //split up the transform matrix
var mapleft=parseFloat(comp[4]) //get left value
var maptop=parseFloat(comp[5])  //get top value
$(".gm-style>div:first>div").css({ //get the map container. not sure if stable
  "transform":"none",
  "left":mapleft,
  "top":maptop,
})

Talvez, as transformações css3 pudessem ser verificadas e convertidas automaticamente para o posicionamento CSS normal durante a renderização e, em seguida, removê-las após a renderização.

estou tendo uma função de captura de tela inconstante.
Funciona após uma recarga completa da página (usando CTLR + R no firefox)

aqui está o meu código, o que basicamente ele faz é gerar uma imagem 64 base / png de uma tela de impressão capturada da janela e o resultado final que coloco em um tag para ver se funciona.

Aqui está a função

função ebfPrintScreen (componentName)
{
html2cavnas
([document.body],
{
registro: verdadeiro,
useCORS: true,
entregue: função (tela)
{
img = canvas.toDataURL ("imagem / jpg");

                                                  console.log(img.length);
                                                  console.log(img);

                                                  var imgComp = $c(conponentName);
                                                  imgComp.img.src = img

                                          }
                      }
                );

}

O objetivo principal é capturar a rota do google map depois de criada, mas como eu disse, às vezes funciona, às vezes não. Alguma pista do que está acontecendo?

Eu estou tendo o mesmo problema. Vou tirar uma imagem do mapa depois de aplicar zoom e panorâmica, e porções maiores, até mesmo todo o mapa, ficam envoltas em marrom claro de repente. Se alguém tiver uma solução para isso no Chrome, por favor me avise.

tentei a solução de @mfirdaus , e funciona para o noraml map view, porém, no streetview, ainda está quebrado ... alguém tem o mesmo problema?

Depois de aplicar a solução de @mfirdaus , consegui capturar a visualização do mapa. Mas de alguma forma, este código abaixo está tornando o mapa inutilizável (mas o html2canvas utilizável):

$(".gm-style>div:first>div").css({ //get the map container. not sure if stable
      "transform":"none",
      "left":mapleft,
      "top":maptop,
    })

Existe uma maneira de "restaurar" o que essa linha está fazendo? Por enquanto, estou chamando a função initMap novamente para que o mapa funcione depois de chamar a função html2canvas com o código de transformação.

O script acima funciona para o Google Maps v3?

Meu requisito é fazer uma captura de tela de um Google Map v3 com uma rota desenhada nele.

Funciona bem no Firefox, mas no Chrome não há marcador ou rota. Já estou usando marcadores personalizados.

Tenho dificuldade em depurar porque não há erro no console e o registro é muito limitado.

Alguém resolveu o problema no Chrome? Eu tentei os scripts de proxy em dois idiomas, mas nenhum parece fazer diferença.

Tenho um problema semelhante, copio / recortei este código da Internet:

  if($.browser.safari) {// Fix for Chrome
    var transform=$(".gm-style>div:first>div").css("transform");
    var comp=transform.split(","); //split up the transform matrix
    var mapleft=parseFloat(comp[4]); //get left value
    var maptop=parseFloat(comp[5]);  //get top value
    $(".gm-style>div:first>div").css({ //get the map container. not sure if stable
      "transform":"none",
      "left":mapleft,
      "top":maptop,
    });
  }

  html2canvas([$("#map")[0]], {
    logging: false,
    useCORS: true,
    onrendered: function (canvas) {
      $('#screenshot').after(canvas);

      if($.browser.safari) {// Fix for Chrome
        $(".gm-style>div:first>div").css({
          left:0,
          top:0,
          "transform":transform
        });
      }
    }
  });

Funciona, mas se eu mover o mapa com o manipulador, ele não funciona. Eu trabalho com marcadores, polígonos, etc. Também funciona no firefox (posso mover o mapa), mas não no cromo.

Qualquer ideia ?

Fixo !

A correção para o cromo que estupidamente copiei / colei não foi acionada.

Eu fiz isso :

  if(window.chrome) {// Fix for Chrome
    var transform=$(".gm-style>div:first>div").css("transform");
    var comp=transform.split(","); //split up the transform matrix
    var mapleft=parseFloat(comp[4]); //get left value
    var maptop=parseFloat(comp[5]);  //get top value
    $(".gm-style>div:first>div").css({ //get the map container. not sure if stable
      "transform":"none",
      "left":mapleft,
      "top":maptop,
    });
  }

  html2canvas([$("#map > div.g-map-canvas > div > div > div:nth-child(1)")[0]], {
    logging: false,
    useCORS: true,
    onrendered: function (canvas) {
      $('#screenshot').after(canvas);

      if(window.chrome) {// Fix for Chrome
        $(".gm-style>div:first>div").css({
          left:0,
          top:0,
          "transform":transform
        });
      }
    }
  });

O seletor muito longo em html2canvas é para ter um mapa sem botões e opções.

Eu trabalho agora, obrigado.

Obrigado @GCorbel Funciona muito bem com a sua solução.

As soluções alternativas acima funcionam para renderizar o mapa, mas os controles superiores estão ausentes ou na posição errada. Alguma ideia?

Isso ainda é um problema com a v1.0.0 ? Em caso afirmativo, você poderia compartilhar um exemplo no jsfiddle .

Este problema foi encerrado automaticamente porque não houve resposta ao nosso pedido de mais informações do autor original. Com apenas as informações que estão atualmente no problema, não temos informações suficientes para tomar medidas. Entre em contato se tiver ou encontre as respostas de que precisamos para que possamos investigar mais a fundo.

@niklasvh Posso confirmar que ainda é um problema com a versão mais recente. Aqui está um violino que criei ao testar esse problema: http://jsfiddle.net/9agom947/4/

O violino mostra o problema conforme descrito na questão stackoverflow vinculada, não necessariamente o que está no OP deste segmento. Se você não movimentar o mapa, não haverá problema em copiar o mapa. Depois de movimentar o mapa, no Chrome, mas não no FireFox, o mapa copiado ficará em branco fora da região que foi inicialmente carregada.

image

A correção fornecida neste tópico parece resolver o problema.

@ Ananda-Pryana Tentei seu jsFiddle, mas a correção parece não funcionar mais. Existe alguma outra solução ?

Desde já, obrigado.

Parece que a última versão do google map (v3.32) lançada recentemente tem um novo renderizador experimental.
https://developers.google.com/maps/documentation/javascript/releases

Isso quebrou a correção. Eu apenas fiz um teste rápido, mas parece que agora as coisas estão quebradas igualmente em todos os navegadores (não apenas para o Chrome), então espero que isso torne mais fácil consertar na próxima versão do html2canvas.

Mas uma solução rápida seria usar a versão mais antiga do gmap, onde a correção ainda estaria funcionando bem.

@ Ananda-Pryana Yup Eu desclassifiquei o gmap, funcionou, obrigado.

Obrigado @ Ananda-Pryana! Tive isso funcionando na semana passada, em seguida, mudei para uma nova plataforma e pensei que foi a mudança que o quebrou. Eu estava indo totalmente para baixo, assumindo que o novo ambiente era o culpado. Fiz o downgrade para 3,30 e está tudo bem.

Parece que, na nova versão do google maps, a transformação é aplicada a diferentes div. Usar a solução de @GCorbel , mas com este seletor (".gm-style> div: first> div: first> div: last> div") parece funcionar. Embora eu ainda não tenha testado completamente.

A dica perfeitamente na versão mais recente. Obrigado!

Hmm, parece que esse problema voltou para mim, eu tenho que deslocar o mapa para ver o problema e quando eu deslocar e usar o Html2Canvas para obter a captura de tela, algumas áreas aparecem em cinza vazio?

Para qualquer um de vocês lidando com o corte de camadas de sobreposição -
O seletor de @GCorbel apenas transforma a camada do mapa do google. Se você tiver outras sobreposições, terá que descobrir em qual div elas estão (por exemplo, $('.gm-style>div:first>div:first>div:first>div:first>div') era uma das minhas divs de sobreposição e aplicar a mesma transformação ao css.

@mylesboone, como você descobriu qual div são as camadas de sobreposição? No momento, estou lutando contra o mesmo problema de camadas de sobreposição sendo cortadas.

Estou usando GmapMarker e GmapPolyline como camadas de sobreposição no momento.

@sunghunOW
Uma solução pode ser encontrada aqui https://github.com/niklasvh/html2canvas/issues/1568
Você pode usar a ferramenta de inspeção do seu navegador para ver quais divs precisarão de transformação.

Melhor solução que encontrei:

    html2canvas($('.gm-style>div:eq(0)')[0],{
        useCORS: true,
        allowTaint: true,
        async:false,
    }).then(canvas => {document.body.appendChild(canvas)});
    html2canvas($('.gm-style>div:eq(0)')[0],{
        useCORS: true,
        allowTaint: true,
        async:false,
    }).then(canvas => {document.body.appendChild(canvas)});

Este canvas não está definido. O seletor de itens deve sair da caixa?

@hseeda Obrigada! Seu seletor estava fazendo o truque para mim!

Aqui está meu seletor ligeiramente modificado que funciona (pelo menos para mim, haha)

const div = document.querySelector('#map > div:first-of-type')

html2canvas(div, {})

No entanto, agora está cortando o logotipo do Google, que sempre deve aparecer para cumprir os termos e condições :(

Bem, bem, vou apenas clonar o nó ou algo assim. Estou lutando contra este mapa há um tempo: D

Isso funciona para mim:

$('#snapshot').on('click',function () {
    html2canvas(document.querySelector('.gm-style'), 
           {useCORS:true, allowTaint: true,async:false} ).then(canvas => {
            document.body.appendChild(canvas)
    });
});

O problema com o mapa em branco ou um erro ao gerar a tela era complicado, mas, eventualmente, o que corrigiu para mim foi adicionar esta configuração:

ignoreElements: (node) => {
        return node.nodeName === 'IFRAME';
      }
html2canvas(mapWrapper, {
      useCORS: true,
      allowTaint: false,
      ignoreElements: (node) => {
        return node.nodeName === 'IFRAME';
      }
    }).then(canvas => {
      const url = canvas.toDataURL('image/png');
      saveAs(url, 'image3.png');
      window.URL.revokeObjectURL(url);
    });

Agradecimentos a @imlinus e @hseeda ! Este seletor funciona perfeitamente para mim! e ainda mantém o logotipo do google, obrigado!

@hseeda Obrigada! Seu seletor estava fazendo o truque para mim!

Aqui está meu seletor ligeiramente modificado que funciona (pelo menos para mim, haha)

const div = document.querySelector('#map > div:first-of-type')

html2canvas(div, {})

No entanto, agora está cortando o logotipo do Google, que sempre deve aparecer para cumprir os termos e condições :(

Bem, bem, vou apenas clonar o nó ou algo assim. Estou lutando contra este mapa há um tempo: D

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

anthonymejia picture anthonymejia  ·  4Comentários

yasergh picture yasergh  ·  5Comentários

deepender87 picture deepender87  ·  4Comentários

wbarrantes picture wbarrantes  ·  3Comentários

dking3876 picture dking3876  ·  4Comentários