Html2canvas: Problem beim Generieren des Kartenbildes (Google Maps)

Erstellt am 6. MĂ€rz 2014  Â·  51Kommentare  Â·  Quelle: niklasvh/html2canvas

Hallo Leute.
Ich muss ein Bild meines Dialogs generieren:

1

Verwenden von html2canvas, aber das erstellte Bild zeigt die Karte nicht an:

2

Mein Code:

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

ich brauche bitte Hilfe.
Danke

Needs More Information

Hilfreichster Kommentar

Scheint, dass in der neuen Version von Google Maps Transformation auf die verschiedenen div angewendet wird. Die Verwendung der Lösung von @GCorbel , jedoch mit diesem Selektor (".gm-style>div:first>div:first>div:last>div") scheint zu funktionieren. Obwohl ich es noch nicht grĂŒndlich getestet habe.

Alle 51 Kommentare

Das Problem ist, dass Google Maps CSS3-Transformationsmatrix verwendet, die in html2canvas nicht vollstÀndig implementiert sind.

Wie mache ich?

Google Maps-Bilder (Bilder auf externem Server)?

Proxy verwenden: https://github.com/niklasvh/html2canvas#how -does-it-work

brcontainer: Ich denke, es ist illegal (direkter Zugriff auf Kartenkacheln von einem anderen Computer /proxy/). Die einzige Möglichkeit besteht darin, CORS zu verwenden.

@bkralik Proxy ist nicht nur fĂŒr Sie, um auf "gesperrte Sites" zuzugreifen, Proxy-Begriff bedeutet etwas anderes, falls der Proxy fĂŒr html2canvas dazu dient, die Javascript-API dazu zu bringen, Bilder von externen Servern zu öffnen, als ob sie sich auf Ihrer lokalen Site befinden wĂŒrden.

Der Proxy macht einen Download auf den externen Server und html2canvas lÀdt das Bild erst, nachdem der Download abgeschlossen ist.

Lesen Sie diese http://en.wikipedia.org/wiki/Same_origin_policy, damit Sie das Thema verstehen.

Wie verwende ich diesen Proxy?

Der Link, den Sie ausgegeben haben, alle Links zur Verwendung von Proxy (in PHP-Sprachen, C# (asp.net), Python und VB (asp classic)).

Vielleicht haben Sie die Links zu den Proxys nicht bemerkt, dann gebe ich Ihnen hier:
https://github.com/niklasvh/html2canvas/wiki/Proxies

Bei der Verwendung einer neuen Bibliothek ist es immer gut, die gesamte README zu lesen.

@brcontainer Ich weiß, was dieser Proxy tut - wenn der Client eine Screenshot-Seite

ich verwende Java.
Haben Sie ein Beispiel fĂŒr die Verwendung des Proxys?

@brcontainer Und wie ich bereits erwĂ€hnt habe, gibt es wirklich Probleme mit CSS3-Transformationen, da Googlemaps, die auf Google Chrome ausgefĂŒhrt werden, sie verwenden, sodass die Karte mit der aktuellen Implementierung nicht ĂŒberprĂŒft werden kann. Vertrauen Sie mir, ich hatte dieses Problem in einem Projekt, das ich geschrieben habe ...

@bkralik Also, wie kann ich tun?
hast du ein beispiel?

Ich programmiere auch in Java (ich habe bereits Proxys in PHP, C# und VB erstellt), aber ich komme nicht rechtzeitig, um einen Proxy in Java zu erstellen, vielleicht kann ich es einfach am Sonntag tun.

Seine Anwendung ist JSP oder "Java Desktop"?

@brcontainer Es ist eine Webanwendung, die JSF, Primefaces, Javascript und Java verwendet

@DanielSBelo JSF-Framework habe ich nie verwendet, ich programmiere in reinem Java, ohne Frameworks, weiß nicht, ob es einfach sein wird, den aktuellen Code mit einem Code in Java-Teil zu implementieren. Ich wollte ihm helfen, aber es ist wirklich nicht an der Zeit.

[bearbeitet]
Informationen zur UnterstĂŒtzung von CSS-Transformationen finden Sie unter: https://github.com/niklasvh/html2canvas#contributing

@DanielSBelo hast du dafĂŒr eine gute Lösung gefunden? Ich habe das gleiche Problem.

Das Speichern einer Karte als Leinwand funktioniert in Firefox gut, aber die Karte kann nicht in Chrome gespeichert werden. Ich glaube nicht, dass es direkt mit der Transformation zusammenhÀngt, sondern eher mit der Art und Weise, wie Chrome mit CORs umgeht. Ich stecke jedoch total fest bei der Suche nach einer Antwort.

@TGOlson Es ist wirklich ein Problem mit CSS3-Transformationen, da die aktuelle Version von html2canvas nur "eine Ebene" der Transformation rendern kann - sie stapelt sie nicht.
Sie können ĂŒberprĂŒfen, ob das Problem in Transformationen liegt, indem Sie einfach mit Google Maps spielen - normalerweise wird ein Screenshot wie dieser angezeigt:
map_2014-08-10_10-44-02
(In CSS ist die gesamte Karte richtig positioniert, aber nach dem Deaktivieren von CSS3 passiert dies)
Die einzige Lösung besteht darin, den gesamten CSS3-Transformationsstapel zu implementieren. Ich weiß nicht, ob es von Niklas in Arbeit ist, aber jemand sollte es tun :-)

abonnieren

Ich habe auch das gleiche Problem - nur in Chrome. Ich verwende html2canvas-proxy-php. Andere Browser funktionieren einwandfrei. Teile der Karte fehlen einfach.. scheint mit der GrĂ¶ĂŸenĂ€nderung der Karte, dem HinzufĂŒgen/Entfernen von Überlagerungen usw. zu tun zu haben

Zu Ihrer Information - Wenn Sie Kartenerfassungsfunktionen schnell zum Laufen bringen mĂŒssen, können Sie jederzeit die Google Streetview- oder statische Karten-API verwenden. Rekonstruieren Sie im Grunde, was der aktuelle Benutzer auf der Karte sieht ( map.getPov usw.) und holen Sie sich dann dieses statische Bild von Google.

Ich glaube nicht, dass dieser Ansatz mit Overlays funktioniert

Ich bin gerade ĂŒber dieses Problem gestolpert. Wenn ich mich nicht irre, zeigt diese Stackoverflow-Frage dieses Problem und ich habe eine Problemumgehung angeboten, indem ich die CSS3-Transformationen gelesen und als normale CSS-Positionen angewendet habe.

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

Vielleicht könnten CSS3-Transformationen ĂŒberprĂŒft und beim Rendern automatisch in die normale CSS-Positionierung konvertiert und nach dem Rendern entfernt werden.

Ich habe eine unkonstante Bildschirmaufnahmefunktion.
Funktioniert nach einem vollstÀndigen Neuladen der Seite (mit STRG+R in Firefox)

Hier ist mein Code, im Grunde erzeugt er ein 64 base/png-Bild eines aufgenommenen Druckbildschirms des Fensters und das Endergebnis, das ich in ein markieren, um zu sehen, ob es funktioniert.

Und hier ist die Funktion

Funktion ebfPrintScreen(KomponentenName)
{
html2cavnas
([document.body],
{
Protokollierung: wahr,
useCORS: wahr,
aufgerendert: Funktion (Leinwand)
{
img = canvas.toDataURL("image/jpg");

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

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

                                          }
                      }
                );

}

Das Hauptziel besteht darin, die Google Map-Route nach der Erstellung zu erfassen, aber wie gesagt, manchmal funktioniert es, manchmal nicht. Irgendeine Ahnung, was los ist?

Ich habe das gleiche Problem. Ich gehe nach dem Zoomen und Schwenken, um ein Bild der Karte zu machen, und grĂ¶ĂŸere Teile, sogar die gesamte Karte, werden plötzlich hellbraun. Wenn jemand eine Lösung fĂŒr dieses Problem in Chrome hat, lassen Sie es mich bitte wissen.

Habe die Lösung von

Nachdem ich die Lösung von

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

Gibt es eine Möglichkeit, die Funktion dieser Zeile "wiederherzustellen"? Im Moment rufe ich die initMap-Funktion erneut auf, damit die Karte nach dem Aufrufen der html2canvas-Funktion mit dem Transformationscode funktioniert.

Funktioniert das obige Skript fĂŒr Google Maps v3?

Meine Anforderung ist, einen Screenshot einer Google Map v3 mit einer darauf gezeichneten Route zu machen.

Es funktioniert gut in Firefox, aber in Chrome gibt es keine Markierung oder Route. Ich verwende bereits benutzerdefinierte Markierungen.

Das Debuggen fÀllt mir schwer, da in der Konsole kein Fehler auftritt und die Protokollierung so begrenzt ist.

Hat jemand das Problem in Chrome gelöst? Ich habe die Proxy-Skripte in zwei Sprachen ausprobiert, aber keine scheint einen Unterschied zu machen.

Ich habe ein Àhnliches Problem, ich kopiere / schneide diesen Code aus dem 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
        });
      }
    }
  });

Es funktioniert, aber wenn ich die Karte mit dem Handler bewege, funktioniert es nicht. Ich arbeite mit Markern, Polygonen usw. Es funktioniert auch in Firefox (ich kann die Karte verschieben), aber nicht in Chrome.

Irgendeine Idee ?

Fest !

Der Fix fĂŒr Chrome, den ich dummerweise kopierte/einfĂŒgte, wurde nicht ausgelöst.

Ich tat dies :

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

Der sehr lange Selektor in html2canvas ist fĂŒr Karte ohne SchaltflĂ€chen und Optionen.

Ich arbeite jetzt, danke.

Danke @GCorbel Es funktioniert sehr gut mit deiner Lösung.

Die oben genannten Problemumgehungen funktionieren beim Rendern der Karte, aber die oberen Steuerelemente fehlen entweder oder befinden sich an der falschen Position. Irgendwelche Ideen?

Ist das immer noch ein Problem mit v1.0.0 ? Wenn ja, könnten Sie bitte ein Beispiel auf jsfiddle teilen .

Dieses Problem wurde automatisch geschlossen, da unsere Anfrage nach weiteren Informationen vom ursprĂŒnglichen Autor nicht beantwortet wurde. Mit den Informationen, die derzeit in der Ausgabe enthalten sind, haben wir nicht genĂŒgend Informationen, um Maßnahmen zu ergreifen. Bitte wenden Sie sich an uns, wenn Sie die Antworten haben oder finden, die wir benötigen, damit wir weitere Nachforschungen anstellen können.

@niklasvh Ich kann bestÀtigen, dass es immer noch ein Problem mit der neuesten Version ist. Hier ist eine Geige, die ich beim Testen dieses Problems erstellt habe: http://jsfiddle.net/9agom947/4/

Die Geige zeigt das Problem wie in der verlinkten Stackoverflow-Frage beschrieben, nicht unbedingt das, was im OP dieses Threads steht. Wenn Sie die Karte nicht verschieben, können Sie die Karte problemlos kopieren. Sobald Sie die Karte in Chrome, aber nicht in FireFox schwenken, ist die kopierte Karte außerhalb der ursprĂŒnglich geladenen Region leer.

image

Der Fix in diesem Thread scheint das Problem zu lösen.

@Ananda-Pryana Ich habe Ihre jsFiddle ausprobiert, aber der Fix scheint nicht mehr zu funktionieren. Gibt es eine andere Lösung?

Danke im Voraus.

Sieht so aus, als hĂ€tte die neueste Version von Google Map (v3.32), die kĂŒrzlich veröffentlicht wurde, einen neuen experimentellen Renderer.
https://developers.google.com/maps/documentation/javascript/releases

Dies hat die Lösung gebrochen. Ich habe nur einen kurzen Test gemacht, aber es scheint, als ob die Dinge jetzt in allen Browsern (nicht nur fĂŒr Chrome) gleich kaputt sind.

Aber ein schneller Workaround wĂ€re, die Ă€ltere Version von gmap zu verwenden, wo der Fix noch gut funktionieren wĂŒrde.

@Ananda-Pryana Yup Ich habe gmap heruntergestuft, funktioniert, danke.

Danke @Ananda-Pryana! Ich hatte das letzte Woche funktionieren lassen und dann auf eine neue Plattform verschoben und ich dachte, der Umzug war es, was es kaputt machte. Ich ging total in ein Rattenloch, in der Annahme, dass die neue Umgebung der Schuldige war. Ich habe auf 3.30 herabgestuft und alles ist gut.

Scheint, dass in der neuen Version von Google Maps Transformation auf die verschiedenen div angewendet wird. Die Verwendung der Lösung von @GCorbel , jedoch mit diesem Selektor (".gm-style>div:first>div:first>div:last>div") scheint zu funktionieren. Obwohl ich es noch nicht grĂŒndlich getestet habe.

Der @rSensation- Tipp hat in der neuesten Version wie ein Zauber funktioniert. Dankeschön!

Hmm, dieses Problem scheint bei mir wieder aufgetreten zu sein, ich muss die Karte schwenken, um das Problem zu sehen, und wenn ich Html2Canvas schwenke und verwende, um den Screenshot zu erhalten, werden einige Bereiche als leeres Grau angezeigt?

An alle, die mit dem Abschneiden von Overlay-Ebenen zu tun haben -
Der Selektor von $('.gm-style>div:first>div:first>div:first>div:first>div') eines meiner Overlay-Divs und wenden Sie dieselbe Transformation auf die CSS an.

@mylesboone wie hast du herausgefunden, welches div die Overlay-Layer sind? Ich kÀmpfe derzeit durch das gleiche Problem, dass Overlay-Ebenen abgeschnitten werden.

Ich verwende derzeit GmapMarker und GmapPolyline als Overlay-Layer.

@sunghunOW
Eine Lösung finden Sie hier https://github.com/niklasvh/html2canvas/issues/1568
Sie können das Inspektionstool Ihres Browsers verwenden, um zu sehen, welche Divs transformiert werden mĂŒssen.

Beste Lösung die ich gefunden habe:

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

Dies gibt mir Canvas ist nicht definiert. Sollte der Selektor der Elemente Word out of the box sein?

@hseeda Danke! Ihr Selektor hat den Trick fĂŒr mich getan!

Hier ist mein leicht modifizierter Selektor, der funktioniert (zumindest fĂŒr mich, haha)

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

html2canvas(div, {})

Jetzt wird jedoch das Google-Logo abgeschnitten, das immer angezeigt werden muss, um die Allgemeinen GeschÀftsbedingungen einzuhalten :(

Nun gut, ich klone einfach den Knoten oder so. Ich kÀmpfe schon seit einiger Zeit gegen diese Karte :D

Das funktioniert bei mir:

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

Das Problem mit einer leeren Karte oder einem Fehler beim Generieren der Leinwand war knifflig, aber letztendlich wurde es fĂŒr mich behoben, indem diese Konfiguration hinzugefĂŒgt wurde:

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

Danke an @imlinus und @hseeda ! Dieser Selektor funktioniert perfekt fĂŒr mich! und es behĂ€lt sogar das Google-Logo, danke!

@hseeda Danke! Ihr Selektor hat den Trick fĂŒr mich getan!

Hier ist mein leicht modifizierter Selektor, der funktioniert (zumindest fĂŒr mich, haha)

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

html2canvas(div, {})

Jetzt wird jedoch das Google-Logo abgeschnitten, das immer angezeigt werden muss, um die Allgemeinen GeschÀftsbedingungen einzuhalten :(

Nun gut, ich klone einfach den Knoten oder so. Ich kÀmpfe schon seit einiger Zeit gegen diese Karte :D

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen