Html2canvas: Exportieren mit Leaflet

Erstellt am 9. Apr. 2015  ·  21Kommentare  ·  Quelle: niklasvh/html2canvas

Hat jemand versucht, html2canvas mit Flugblatt zu verwenden. Ich war in der Lage, html2canvas dazu zu bringen, mit Google Maps zu arbeiten, aber ich muss es jetzt für die Broschüre zum Laufen bringen, wenn ich die Karte nach links, rechts, oben oder unten schwenke, fehlen mir einige der Kacheln aus der Broschüre. Auch bekomme ich mein Overlay nicht mehr. Ich habe ein grobes jsfiddle erstellt, um das Problem der fehlenden Kacheln zu zeigen. Angehängt ist auch ein Screenshot von meinem Code
missingtiles

https://jsfiddle.net/japiasente/7ybndo5L/

Needs More Information

Hilfreichster Kommentar

Es braucht ein paar hässliche Hacks, um es zum Laufen zu bringen. Hier ist ein einfaches Beispiel ohne Korrekturen:

http://jsfiddle.net/djwbra47/

Es gibt mehrere Probleme:

  1. Die kreisförmige Markierung wird auf einen Viertelkreis gekürzt. Es sieht so aus, als würde html2canvas Elemente beschneiden, BEVOR irgendwelche Transformationen angewendet werden. Der Marker würde ohne Transformationen bei 0,0 zentriert werden, also wird er auf den Viertelkreis geclippt, der an dieser Position sichtbar wäre. Anschließend transformiert html2canvas es in den tatsächlichen Speicherort. Ich habe es behoben, indem ich den linken und den oberen Rand auf 0 anstatt auf negativ gesetzt habe (so dass die gesamte Markierung bei 0,0 sichtbar wäre) und dann die Transformationen um denselben Betrag angepasst habe. (Und dann ändern Sie diese Werte natürlich wieder, nachdem die Leinwand erfasst wurde.)
  2. Die Zeile wird an der falschen Stelle angezeigt. Es sieht so aus, als würde html2canvas Transformationen auf die SVG-Pfade ZWEIMAL anwenden. Ohne Korrekturen wird die Linie zu weit oben links angezeigt. Wenn Sie seine Transformation auf 0 ändern, wird derselbe Abstand zu weit unten rechts angezeigt. Ich musste die Transformation auf die Hälfte der ursprünglichen Werte einstellen, damit sie funktioniert.
  3. Wenn Sie die Karte schwenken, werden die Kacheln auf die ursprüngliche Ausdehnung zugeschnitten. Dies ist das gleiche Problem wie Nummer 1: Leaflet schwenkt die Karte, indem es das Kartenfenster transformiert, und html2canvas schneidet die Kacheln ab, bevor diese Transformation angewendet wird. Um das Problem zu beheben, fügen Sie die X- und Y-Werte der Transformation zu den linken und oberen Werten jedes Bildes hinzu und setzen Sie dann ihre Transformationen auf 0.
  4. Wenn Sie die Karte schwenken, zeichnet html2canvas die Kacheln über die Markierung und die Linie, sodass sie nicht mehr sichtbar sind. Dies wird behoben, wenn Sie die Änderungen in Nummer 3 vornehmen, aber ich verstehe nicht warum. Vielleicht ändert sich die Zeichenreihenfolge, wenn die Eigenschaften eines Elements aktualisiert werden?

Hier die gefixte Version:
http://jsfiddle.net/oo2yms1h/

Es gibt noch ein Problem, das ich noch nicht gelöst habe: Wenn Sie die Karte schwenken, sodass sich die Linie in der Nähe des rechten Rands befindet, wird sie nicht auf der Leinwand angezeigt. Aber ich vermute, es ist ein weiteres Ergebnis des html2canvas-Clippings vor der Transformation.

Noch eine Anmerkung: Der Standard-Leaflet-Marker ist ein Bild, das von cdn.leaflet.com gehostet wird und einen CORS-Fehler ausgibt, was bedeutet, dass es nicht auf der Leinwand angezeigt wird. Jeder, der es mit html2canvas verwendet, müsste das Symbol selbst hosten oder zu einem anderen Markierungsstil wechseln.

JAPiasente, sieht so aus, als könnte mein Fix in Nummer 3 angepasst werden, um Ihre Kachel- und Panning-Probleme zu lösen. Außerdem sind Ihre Markierungen SVG-Pfade und scheinen unter dem gleichen Doppeltransformationsproblem zu leiden wie meine Zeile in Nummer 2, sie werden zu weit oben links angezeigt. Hier ist eine Version mit diesen Änderungen:

https://jsfiddle.net/6tn0zy48/

Alles wird an der richtigen Stelle angezeigt, außer dass die Markierungen weiter oben als am unteren Rand der Karte abgeschnitten werden. Anscheinend ist es das gleiche Problem, an dem ich noch arbeite.

Alle 21 Kommentare

Geben Sie ein Beispiel für das Problem mit http://jsfiddle.net an

Ich habe die jsfiddle hinzugefügt. https://jsfiddle.net/japiasente/7ybndo5L/

Es braucht ein paar hässliche Hacks, um es zum Laufen zu bringen. Hier ist ein einfaches Beispiel ohne Korrekturen:

http://jsfiddle.net/djwbra47/

Es gibt mehrere Probleme:

  1. Die kreisförmige Markierung wird auf einen Viertelkreis gekürzt. Es sieht so aus, als würde html2canvas Elemente beschneiden, BEVOR irgendwelche Transformationen angewendet werden. Der Marker würde ohne Transformationen bei 0,0 zentriert werden, also wird er auf den Viertelkreis geclippt, der an dieser Position sichtbar wäre. Anschließend transformiert html2canvas es in den tatsächlichen Speicherort. Ich habe es behoben, indem ich den linken und den oberen Rand auf 0 anstatt auf negativ gesetzt habe (so dass die gesamte Markierung bei 0,0 sichtbar wäre) und dann die Transformationen um denselben Betrag angepasst habe. (Und dann ändern Sie diese Werte natürlich wieder, nachdem die Leinwand erfasst wurde.)
  2. Die Zeile wird an der falschen Stelle angezeigt. Es sieht so aus, als würde html2canvas Transformationen auf die SVG-Pfade ZWEIMAL anwenden. Ohne Korrekturen wird die Linie zu weit oben links angezeigt. Wenn Sie seine Transformation auf 0 ändern, wird derselbe Abstand zu weit unten rechts angezeigt. Ich musste die Transformation auf die Hälfte der ursprünglichen Werte einstellen, damit sie funktioniert.
  3. Wenn Sie die Karte schwenken, werden die Kacheln auf die ursprüngliche Ausdehnung zugeschnitten. Dies ist das gleiche Problem wie Nummer 1: Leaflet schwenkt die Karte, indem es das Kartenfenster transformiert, und html2canvas schneidet die Kacheln ab, bevor diese Transformation angewendet wird. Um das Problem zu beheben, fügen Sie die X- und Y-Werte der Transformation zu den linken und oberen Werten jedes Bildes hinzu und setzen Sie dann ihre Transformationen auf 0.
  4. Wenn Sie die Karte schwenken, zeichnet html2canvas die Kacheln über die Markierung und die Linie, sodass sie nicht mehr sichtbar sind. Dies wird behoben, wenn Sie die Änderungen in Nummer 3 vornehmen, aber ich verstehe nicht warum. Vielleicht ändert sich die Zeichenreihenfolge, wenn die Eigenschaften eines Elements aktualisiert werden?

Hier die gefixte Version:
http://jsfiddle.net/oo2yms1h/

Es gibt noch ein Problem, das ich noch nicht gelöst habe: Wenn Sie die Karte schwenken, sodass sich die Linie in der Nähe des rechten Rands befindet, wird sie nicht auf der Leinwand angezeigt. Aber ich vermute, es ist ein weiteres Ergebnis des html2canvas-Clippings vor der Transformation.

Noch eine Anmerkung: Der Standard-Leaflet-Marker ist ein Bild, das von cdn.leaflet.com gehostet wird und einen CORS-Fehler ausgibt, was bedeutet, dass es nicht auf der Leinwand angezeigt wird. Jeder, der es mit html2canvas verwendet, müsste das Symbol selbst hosten oder zu einem anderen Markierungsstil wechseln.

JAPiasente, sieht so aus, als könnte mein Fix in Nummer 3 angepasst werden, um Ihre Kachel- und Panning-Probleme zu lösen. Außerdem sind Ihre Markierungen SVG-Pfade und scheinen unter dem gleichen Doppeltransformationsproblem zu leiden wie meine Zeile in Nummer 2, sie werden zu weit oben links angezeigt. Hier ist eine Version mit diesen Änderungen:

https://jsfiddle.net/6tn0zy48/

Alles wird an der richtigen Stelle angezeigt, außer dass die Markierungen weiter oben als am unteren Rand der Karte abgeschnitten werden. Anscheinend ist es das gleiche Problem, an dem ich noch arbeite.

Das letzte verbleibende Problem zu beheben war nicht schwer, es war nur eine Frage der Transformation auf 0 zu setzen und stattdessen left und top zu verwenden.

Mein einfaches Beispiel, aktualisiert:
http://jsfiddle.net/oo2yms1h/1/

Und mein überarbeiteter Fix für Ihre Karte:
https://jsfiddle.net/6tn0zy48/1/

Ich habe in Chrome gearbeitet und gerade festgestellt, dass mein Fix in Firefox und IE nicht funktioniert. Sie gaben die Transformationsstile als translate statt translate3d an, und mein Code ging davon aus, dass es immer translate3d sein würde. Und sie positionierten die Kacheln mit translate statt left und top wie in Chrome. Dieses aktualisierte Beispiel wurde für alle drei Browser überarbeitet. Kacheln und Markierungssymbole funktionieren in allen dreien, aber ich kann die SVG-Pfade immer noch nicht in Firefox und IE anzeigen.

http://jsfiddle.net/oo2yms1h/3/

IE benötigte html2canvas.svg, bevor es die Linie anzeigen würde, und es funktioniert auch nicht, wenn Transformationen oder Left/Top-Eigenschaften auf der SVG-Ebene festgelegt sind. Dieses Beispiel funktioniert im IE und fast auch in Firefox:

http://jsfiddle.net/oo2yms1h/5/

Damit die Zeile in Firefox angezeigt wird, müssen Sie auch zur base64-Codierung wechseln, indem Sie die in #648 erwähnte Änderung an html2canvas vornehmen:
https://github.com/niklasvh/html2canvas/pull/648/files

Danke für all eure Hilfe bisher. Das einzige letzte Problem ist jetzt, wenn ich ein SVG-Overlay darauf habe, spielt IE nicht gut damit. Die Karte und das SVG-Overlay funktionieren gut in Chrom. Irgendwelche Ideen?

@CraigVA Du bist unglaublich. Ich habe gerade die letzten zwei Tage damit verbracht, dieses Problem zu beheben. Ich wünschte, ich wäre früher auf Ihre jsfiddles gestoßen. Danke!!!

Ich hatte ein Problem mit der @CraigVA- Lösung, bei dem, wenn ich die Karte überhaupt schwenke, die Überlagerungen von den Kacheln abweichen würden.

Um dem entgegenzuwirken, war alles, was ich getan habe, eine redraw()-Funktion, die die Ansicht für eine Sekunde auf einen anderen Ort im Ozean setzte und dann die Ansicht wieder dorthin zurücksetzte, wo sie war. Funktioniert gut.

function redraw() {
    var lat_tmp = map.getCenter().lat;
    var lng_tmp = map.getCenter().lng;
    map.setView([-66.22149259832975, -1.142578125]);
    setTimeout(function () {
        waitForTilesToLoad()
    }, 50000);
    map.setView([lat_tmp, lng_tmp]);
}

Falls jemand darauf stößt und das gleiche Problem hat.

Hallo, danke für diesen Hack, er funktioniert gut, außer für Pfadebenen und für große TileLayers.

  • Wenn ein Teil einer Pfadebene (Polygon/Polylinie) außerhalb der ursprünglichen Kartengrenzen liegt, wird er beim Verschieben der Karte von html2canvas abgeschnitten.
    Ich habe Ihren Code hier http://jsfiddle.net/c8LL4qfo/ mit einer längeren Polylinie aktualisiert. Versuchen Sie, die Karte zu verschieben, Sie werden sehen, dass die Linie in der Leinwand abgeschnitten ist.
    Irgendwelche Ideen, wie man diesen Fehler beheben kann?

  • Zweiter Punkt: Wenn tileLayers zu groß sind, wartet html2canvas nicht darauf, dass die Karte gerendert wird. Auch mit UseCors=true. Gibt es eine Möglichkeit zu warten, bis die TileLayers geladen werden? Ich habe über die Verwendung des Ladeereignisses nachgedacht, aber ich habe keine Ahnung, wie ich das könnte.

Danke

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

Ich habe dieses Problem mit React gelöst: Die Leaflet-Komponente wird nach dem Verschieben der Karte zurückgesetzt, wobei das letzte Zentrum und die letzte Zoomstufe beibehalten werden. Es gibt keinen Konflikt mehr mit html2canvas, da die bereitgestellte Karte eine neue Karte ist.

Ok, ich habe das Update im jsfiddle-Code hier gemacht: http://jsfiddle.net/2zkLkLxc/
Es gibt keine Clipping-Probleme mehr mit V1.0.0, aber wir haben Rückenprobleme mit dem Clipping von Symbolen (jederzeit) und dem Clipping von Kacheln, wenn die Karte verschoben wird.
Ich habe versucht, die Hacks auf Kacheln zu entfernen, und es ändert nichts.

Es ist seltsam, weil ich in meinem Code auf v.1.0.0 aktualisiert habe und keine Symbole abgeschnitten werden.

Dieses Problem wurde automatisch geschlossen, da auf unsere Anfrage nach weiteren Informationen des ursprünglichen Autors keine Antwort erfolgt ist. Mit nur den Informationen, die derzeit in der Ausgabe enthalten sind, haben wir nicht genügend Informationen, um Maßnahmen zu ergreifen. Bitte kontaktieren Sie uns, wenn Sie die Antworten haben oder finden, die wir benötigen, damit wir weiter nachforschen können.

Ich habe das gleiche Problem, aber ich habe Leaflet Map anstelle von Google Map verwendet.
Der Code ist unten

var transform=$(.leaflet-map-pane").css("transform");
wenn (transformieren) {
var c = transform.split(",");
var d = parseFloat(c[4]);
var h = parseFloat(c[5]);
$(".leaflet-map-pane").css({
"transformieren": "keine",
"links": d,
"oben": h
})
}
html2canvas(document.body).then(function(canvas){
$(".leaflet-map-pane").css({
links: 0,
oben: 0,
"umwandeln": umwandeln
})
} // Hier wird html2canvas 1.0.0-alpha.9 verwendet

@CraigVA Vielen Dank!

Ich habe im Moment ein Problem mit Stackoverflow bezüglich des Clipping-Problems. Ich verwende Merkblatt 1.3.1. Wenn mir jemand eine Anleitung geben kann, wäre ich sehr dankbar. Das Problem ist hier.

@niklasvh Das Problem besteht immer noch: http://jsfiddle.net/x3jzsg9b/4/

Das Problem ist immer noch da: https://jsfiddle.net/x512pgjt/269/

@amarandon @bomba1990

Versuchen Sie, das Renderer-Padding von Ihrer Karte zu entfernen. Es hat für mich funktioniert.

map.getRenderer(map).options.padding = 0;

Das hat wunderbar funktioniert!

html2canvas(document.querySelector("#mapid"), {
allowTaint: wahr,
useCORS: wahr
}).dann(Leinwand => {
document.body.appendChild (Leinwand)
});

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen