Html2canvas: Problème pour générer l'image de la carte (Google Maps)

Créé le 6 mars 2014  ·  51Commentaires  ·  Source: niklasvh/html2canvas

salut les gars.
J'ai besoin de générer une image de mon dialogue :

1

Utilisation de html2canvas, mais la création de l'image n'affiche pas la carte :

2

Mon code :

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

j'ai besoin d'aide s'il vous plait.
Merci

Needs More Information

Commentaire le plus utile

Il semble que dans la nouvelle version de google maps, la transformation soit appliquée aux différentes div. L' utilisation de la solution de (".gm-style>div:first>div:first>div:last>div") semble fonctionner. Même si je ne l'ai pas encore testé à fond.

Tous les 51 commentaires

Le problème est que google maps utilise la matrice de transformation CSS3, qui n'est pas entièrement implémentée dans html2canvas.

Comment fais-je?

Images Google Maps (images sur serveur externe) ?

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

brcontainer : Je pense que c'est illégal (accéder aux tuiles de carte directement depuis un autre ordinateur /proxy/). Le seul moyen est d'utiliser CORS.

Le proxy

Le proxy effectue un téléchargement sur le serveur externe et html2canvas ne charge l'image qu'une fois le téléchargement terminé.

Lisez ceci http://en.wikipedia.org/wiki/Same_origin_policy pour que vous compreniez le sujet.

comment utiliser ce proxy ?

Le lien que vous avez passé à tous les liens vers l'utilisation de proxy (en langages php​​, C# (asp.net), python et VB (asp classic)).

Peut-être que vous n'avez pas remarqué les liens vers les proxys, alors je vais vous donner ici :
https://github.com/niklasvh/html2canvas/wiki/Proxies

Lorsque vous utilisez une nouvelle bibliothèque, il est toujours bon de lire l'intégralité du fichier README.

@brcontainer Je sais ce que fait ce proxy - lorsque le client souhaite effectuer une capture d'écran, le SERVEUR télécharge toutes les images dans le dossier local, puis le client les charge. Mais c'est faux - parce que google n'autorise pas l'utilisation directe de leurs serveurs de tuiles - et de leur point de vue, quelqu'un télécharge soudainement des charges de tuiles sur le serveur sans afficher la page Web...

j'utilise Java.
tu as un exemple pour utiliser le proxy ?

@brcontainer Et comme je l'ai mentionné, il y a vraiment un problème avec les transformations CSS3, car les googlemaps fonctionnant sur Google Chrome les utilisent, donc la carte ne peut pas être visualisée avec l'implémentation actuelle. Croyez-moi, j'ai eu ce problème dans le projet que j'ai écrit...

@bkralik Alors, comment puis-je faire?
avez-vous un exemple?

Je programme aussi en java (j'ai déjà créé des proxys en PHP, C# et VB), mais je n'ai pas le temps de créer un proxy en Java, peut-être que je pourrai le faire dimanche.

Son application est JSP ou "Java Desktop" ?

@brcontainer C'est une application web, utilisant JSF, Primefaces, Javascript et Java

@DanielSBelo Framework JSF que je n'ai jamais utilisé, je programme en pur Java, sans frameworks, je ne sais pas s'il sera facile d'implémenter le code actuel avec un code en partie java. Je voulais l'aider, mais ce n'est vraiment pas opportun.

[édité]
À propos de la prise en charge des transformations css, lisez : https://github.com/niklasvh/html2canvas#contributing

@DanielSBelo avez-vous trouvé une bonne solution pour cela ? J'ai le même problème.

L'enregistrement d'une carte en tant que canevas fonctionne bien dans Firefox, mais ne parvient pas à enregistrer la carte dans Chrome. Je ne pense pas que cela soit directement lié à la transformation, mais plus probablement à la façon dont Chrome gère les COR. Je suis totalement bloqué à essayer de trouver une réponse, cependant.

@TGOlson C'est vraiment un problème avec les transformations CSS3, car la version actuelle de html2canvas n'est capable de rendre qu'"un niveau" de transformation - elle ne les empile pas.
Vous pouvez vérifier que le problème réside dans les transformations simplement en jouant avec google maps - généralement, une capture d'écran comme celle-ci est donnée :
map_2014-08-10_10-44-02
(En css, toute la carte est positionnée correctement mais après avoir désactivé css3, cela se produit)
La seule solution consiste à implémenter une pile de transformations CSS3 entière. Je ne sais pas si c'est en cours par Niklas, mais quelqu'un devrait le faire :-)

s'abonner

J'ai également le même problème - uniquement dans Chrome. J'utilise html2canvas-proxy-php. Les autres navigateurs fonctionnent très bien. Des parties de la carte sont simplement manquantes.. semble être lié au redimensionnement de la carte, à l'ajout/suppression de superpositions, etc.

Pour info - si vous avez besoin d'une fonctionnalité de capture de carte rapidement opérationnelle, vous pouvez toujours utiliser l'API google streetview ou static maps. Fondamentalement, reconstruisez ce que l'utilisateur actuel regarde sur la carte ( map.getPov , etc.) puis récupérez cette image statique de google.

Je ne pense pas que cette approche fonctionne avec des superpositions

Je viens de tomber sur ce problème. Si je ne me trompe pas, cette question de débordement de pile présente ce problème et j'ai proposé une solution de contournement en lisant les transformations css3 et en les appliquant comme des positions CSS normales.

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,
})

Peut-être que les transformations CSS3 pourraient être vérifiées et converties automatiquement en positionnement CSS normal pendant le rendu, puis les supprimer après le rendu.

j'ai une fonction de capture d'écran inconstante.
Fonctionne après un rechargement complet de la page (en utilisant CTLR + R sur firefox)

voici mon code, ce qu'il fait en gros, c'est de générer une image 64 base/png d'une capture d'écran de la fenêtre et le résultat final que j'ai mis dans un tag pour voir si cela fonctionne.

Voici la fonction

fonction ebfPrintScreen (nom du composant)
{
html2cavnas
([document.corps],
{
journalisation : vrai,
useCORS : vrai,
rendu : fonction (toile)
{
img = canvas.toDataURL("image/jpg");

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

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

                                          }
                      }
                );

}

L'objectif principal est de capturer l'itinéraire google map après sa création, mais comme je l'ai dit, parfois cela fonctionne, parfois non. Une idée de ce qui se passe ?

Je rencontre le même problème. Je vais prendre une image de la carte après avoir zoomé et fait un panoramique et des portions plus grandes, voire toute la carte, deviennent soudainement enveloppées de brun clair. Si quelqu'un a un correctif pour cela dans Chrome, veuillez me le faire savoir.

essayé la solution de @mfirdaus , et cela fonctionne pour la vue de la carte noraml, cependant, dans Streetview, il est toujours cassé... quelqu'un a-t-il le même problème?

Après avoir appliqué la solution de @mfirdaus , j'ai pu capturer la vue de la carte. Mais d'une manière ou d'une autre, ce code ci-dessous rend la carte inutilisable (mais le html2canvas est utilisable):

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

Existe-t-il un moyen de « restaurer » ce que fait cette ligne ? Pour l'instant, j'appelle à nouveau la fonction initMap afin que la carte fonctionne après avoir appelé la fonction html2canvas avec le code de transformation.

Le script ci-dessus fonctionne-t-il pour Google Maps v3 ?

Mon exigence est de prendre une capture d'écran d'une Google Map v3 avec un itinéraire tracé dessus.

Cela fonctionne bien dans Firefox, mais dans Chrome, il n'y a pas de marqueur ni de route. J'utilise déjà des marqueurs personnalisés.

J'ai du mal à déboguer car il n'y a pas d'erreur dans la console et la journalisation est tellement limitée.

Quelqu'un a-t-il résolu le problème dans Chrome ? J'ai essayé les scripts proxy en deux langues, mais aucun ne semble faire de différence.

J'ai un problème similaire, je copie/coupe ce code sur 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
        });
      }
    }
  });

Cela fonctionne mais si je déplace la carte avec le gestionnaire, cela ne fonctionne pas. Je travaille avec des marqueurs, des polygones, etc. Cela fonctionne également dans Firefox (je peux déplacer la carte) mais pas dans Chrome.

Une idée ?

Corrigé !

Le correctif pour chrome que j'ai bêtement copié/collé n'a pas été déclenché.

J'ai fait ça :

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

Le très long sélecteur de html2canvas sert à avoir une carte sans boutons ni options.

Je travaille maintenant, merci.

Merci @GCorbel Cela fonctionne très bien avec votre solution.

Les solutions de contournement ci-dessus fonctionnent pour le rendu de la carte, mais les commandes supérieures sont manquantes ou dans la mauvaise position. Des idées?

Est-ce toujours un problème avec la v1.0.0 ? Si oui, pourriez-vous s'il vous plaît partager un exemple sur jsfiddle .

Ce problème a été automatiquement fermé car il n'y a pas eu de réponse à notre demande d'informations supplémentaires de la part de l'auteur d'origine. Avec seulement les informations qui sont actuellement dans le problème, nous n'avons pas assez d'informations pour prendre des mesures. Veuillez nous contacter si vous avez ou trouvez les réponses dont nous avons besoin afin que nous puissions approfondir nos recherches.

@niklasvh Je peux confirmer qu'il s'agit toujours d'un problème avec la dernière version. Voici un violon que j'ai créé en testant ce problème : http://jsfiddle.net/9agom947/4/

Le violon montre le problème tel que décrit dans la question liée au débordement de pile, pas nécessairement ce qu'il y a dans l'OP de ce fil. Si vous ne déplacez pas la carte, il n'y a aucun problème pour que la carte soit copiée. Une fois que vous avez fait un panoramique sur la carte, dans Chrome mais pas dans FireFox, la carte copiée sera vide en dehors de la région initialement chargée.

image

Le correctif donné dans ce fil semble résoudre le problème.

@Ananda-Pryana J'ai essayé votre jsFiddle mais le correctif ne semble plus fonctionner. N 'y a-t-il pas une autre solution ?

Merci d'avance.

On dirait que la dernière version de google map (v3.32) publiée récemment a un nouveau moteur de rendu expérimental.
https://developers.google.com/maps/documentation/javascript/releases

Cela a cassé le correctif. Je n'ai fait qu'un test rapide, mais il semble que maintenant les choses soient cassées de la même manière dans tous les navigateurs (pas seulement pour Chrome), donc j'espère que cela facilitera la réparation dans la prochaine version de html2canvas ?

Mais une solution de contournement rapide consisterait à utiliser l'ancienne version de gmap, où le correctif fonctionnerait toujours correctement.

@Ananda-Pryana Oui, j'ai déclassé gmap, j'ai travaillé, merci.

Merci @Ananda-Pryana ! J'ai fait fonctionner cela la semaine dernière, puis je l'ai déplacé sur une nouvelle plate-forme et j'ai pensé que le déménagement était ce qui l'a cassé. J'étais totalement en train de sombrer dans un trou à rats en supposant que le nouvel environnement était le coupable. J'ai rétrogradé à 3.30 et tout va bien.

Il semble que dans la nouvelle version de google maps, la transformation soit appliquée aux différentes div. L' utilisation de la solution de (".gm-style>div:first>div:first>div:last>div") semble fonctionner. Même si je ne l'ai pas encore testé à fond.

L' astuce

Hmm semble que ce problème est de retour pour moi, je dois faire un panoramique sur la carte pour voir le problème et lorsque je fais un panoramique et que j'utilise Html2Canvas pour obtenir la capture d'écran, certaines zones s'affichent en gris blanc?

À tous ceux d'entre vous qui ont à faire à la suppression des calques de superposition --
Le sélecteur de @GCorbel ne transforme que la couche de la carte Google. Si vous avez d'autres superpositions, vous devrez trouver dans quelle div elles se trouvent (par exemple, $('.gm-style>div:first>div:first>div:first>div:first>div') était l'une de mes div de superposition et appliquer la même transformation au css.

@mylesboone, comment avez-vous trouvé la division des calques de superposition ? Je suis actuellement aux prises avec le même problème de coupure des couches de superposition.

J'utilise GmapMarker et GmapPolyline comme calques de superposition pour le moment.

@sunghunOW
Une solution peut être trouvée ici https://github.com/niklasvh/html2canvas/issues/1568
Vous pouvez utiliser l'outil d'inspection de votre navigateur pour voir quelles div auront besoin d'être transformées.

Meilleure solution que j'ai trouvée :

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

Cela me donne le canevas n'est pas défini. Le sélecteur des éléments doit-il sortir de la boîte ?

@hseeda Merci ! Votre sélecteur faisait le tour pour moi !

Voici mon sélecteur légèrement modifié qui fonctionne (du moins pour moi, haha)

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

html2canvas(div, {})

Cependant, maintenant, il coupe le logo Google qui doit toujours apparaître afin de se conformer aux termes et conditions :(

Eh bien, je vais juste cloner le nœud ou quelque chose. Je me bats contre cette map depuis un moment maintenant :D

Cela fonctionne pour moi:

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

Le problème avec une carte vierge ou une erreur lors de la génération du canevas était délicat, mais finalement, ce qui l'a résolu pour moi a été d'ajouter cette configuration :

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

Merci à @imlinus et @hseeda ! Ce sélecteur fonctionne parfaitement pour moi ! et il garde même le logo google, merci !

@hseeda Merci ! Votre sélecteur faisait le tour pour moi !

Voici mon sélecteur légèrement modifié qui fonctionne (du moins pour moi, haha)

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

html2canvas(div, {})

Cependant, maintenant, il coupe le logo Google qui doit toujours apparaître afin de se conformer aux termes et conditions :(

Eh bien, je vais juste cloner le nœud ou quelque chose. Je me bats contre cette map depuis un moment maintenant :D

Cette page vous a été utile?
0 / 5 - 0 notes