Canvas-Zeichnung mit jsPDF

Günther Weber

Grünschnabel
Ich hab ein JavaScript Programm das eine Zeichnung auf einem Canvas erstellt.
Die Abmessungen der Zeichnung werden automatisch auf die Fenstergröße skaliert.

Wenn ich die Zeichnung als PDF ausgeben will nutze ich folgenden Code.

Javascript:
    var imgData = mycanvas.toDataURL("image/jpeg", 1.0);
    var pdf = new jsPDF(  "portrait",  "mm", "a4");
    pdf.addImage(imgData, 'JPEG', 0, 0);
    pdf.save("download.pdf");

Leider wird die Zeichnung dann irgendwie abhängig von der Fenstergröße skaliert.
Nutze ich die volle Fenstergröße meines 27 Zoll Monitors, wird ein Teil der Zeichnung abgeschnitten. (Bild 1)
Verkleinere ich das Fenster auf Notebook-Größe, wird das A4 Blatt nicht voll ausgefüllt. (Bild 2)
Nur mit einer gefühlvollen Fenster-Verkleinerung kann ich das A4 Blatt ausfüllen. (Bild 3)

Ich möchte aber unabhängig von der Fenstergröße immer mein A4 Blatt ausfüllen.

Dann kommt noch hinzu, dass die PDF-Datei eine sehr schlechte Qualität hat.
Eine gute Qualität bekomme ich wenn ich wenn ich den Skalierungsfaktor beim Zeichnen auf dem Canvas auf 8 stelle.
Im Bild 1 beträgt er etwa 4, in den Bildern 2 und 3 entsprechend weniger.
Mit diesem Skalierungsfaktor kann ich natürlich keine komplette Zeichnung auf dem Monitor sehen,
aber auch in der PDF-Datei sehe ich nur das was auf dem Monitor ist, genauer gesagt, sogar etwas weniger. (Bild 4)

Ich muß also vor der PDF-Erstellung eine sehr große Canvas-Zeichnung erstellen, die auf dem Bildschirm nicht angezeigt wird.
Wie geht das?

fast vergessen: Danke!
 

Anhänge

  • Unbenannt-1.jpg
    Unbenannt-1.jpg
    104,8 KB · Aufrufe: 7
Interessantes Thema. Vollständig kann ich es nicht beantworten, aber zum Einpassen in die Seite habe ich dies gefunden:
https://stackoverflow.com/questions/36472094/how-to-set-image-to-fit-width-of-the-page-using-jspdf
Dies bedeutet höchstwahrscheinlich einen Skalierungsvorgang, der dein Problem mit der Qualität wahrscheinlich verschlimmert.
Wenn ich mir die Bilder ansehe, sieht das gar nicht wie ein Foto aus sondern eher wie eine technische Zeichnung. In dem Fall könnte eine Vektorgrafik günstiger sein.
SVG nach PDS zu konvertieren, scheint auch eine Sache für sich zu sein:
https://stackoverflow.com/questions/23340610/how-to-create-easily-a-pdf-from-a-svg-with-jspdf
aber dem letzten Beitrag nach scheint es eine funktionierende Lösung zu geben.
 
Das mit dem Einpassen auf A4 habe ich zwischenzeitlich auch herausgefunden:
pdf.addImage(imgData, 'JPEG', 0, 0, 210, 297);

Ja, es ist eine technische Zeichnung.

Als ich mit dem ersten Projekt (inzwischen sind es 3) angefangen habe, hatte ich mich für SVG entschieden,
dann aber festgestellt dass nicht alles geht was ich benötige und habe dann auf Canvas umgestellt.

Zurück nach SVG kann eigentlich keine Lösung für mich sein. Ich denke aber darüber nach...
Danke!
 
In der Nacht ist mir im Halbschlaf die Lösung eingefallen:

Javascript:
function toPDF() {
    zfit(); // Zoom berechnen und Zeichnung einpassen
    var pdf = new jsPDF("portrait", "mm", "a4");
    var Anzahl = 4; // je größer der Wert, desto besser die Qualität
    Zoom *= Anzahl;
    var wy = window.innerHeight / Anzahl;
    var wx = wy / 297 * 210;
    var by = 297/Anzahl;
    var bx = 210/Anzahl;
    for (var iy = 0; iy < Anzahl; iy++) {
        for (var ix = 0; ix < Anzahl; ix++) {
            NullPunkt.x = -wx * Anzahl  * ix;
            NullPunkt.y = -wy * Anzahl  * iy;
            zeichnecanvas();  // Zeichnungsausschnitt darstellen
            var imgData = mycanvas.toDataURL("image/jpeg", 1.0);
            pdf.addImage(imgData, 'JPEG', bx*ix, by*iy, bx, by);
        }
    }
    pdf.save("download.pdf");
    zfit(); // Zoom berechnen und Zeichnung einpassen
}

1a Qualität :)
 
Man kann die Qualität (und Dateigröße) auch je nach Fenstergröße einschränken:
Javascript:
    var Anzahl = 2; // je größer der Wert, desto besser die Qualität
    if (window.innerHeight < 500) Anzahl = 4;
    else if (window.innerHeight < 800) Anzahl = 3;
 
Super, dass Du eine Lösung gefunden hast! Um es zu verstehen, muss man wahrscheinlich das Umfeld kennen (was macht zeichnecanvas()):
 
zeichnecanvas erstellt die Zeichnung, das ist natürlich ganz individuell.

Um zum Beispiel eine Linie zu zeichnen:

Javascript:
            canvascontext.beginPath();
            var X1 = NullPunkt.x + x1 * mstab * Zoom;
            var Y1 = NullPunkt.y - y1 * mstab * Zoom;
            var X2 = NullPunkt.x + x2 * mstab * Zoom;
            var Y2 = NullPunkt.y - y2 * mstab * Zoom;               
            canvascontext.moveTo(X1,Y1);
            canvascontext.lineTo(X2,Y2);
            canvascontext.stroke();

NullPunkt und Zoom kommen ja oben in meiner Lösung schon vor.
Ich kann mit der Maus die gesamte Zeichnung verschieben indem ich den NullPunkt verändere,
Ich kann über Funktionstasten den Zoom vergrößern oder verkleinern,
diese beiden bereits vorhandenen Variablen kann ich für die PDF Erstellung einfach verwenden.

mstab ist ein Faktor mit dem meine 1:1 Geometrie auf DIN A4 eingepasst wird.
Zoom ist der Faktor mit der meine A4-Zeichnung auf das Fenster skaliert wird (oder eben weiter vergrößert oder verkleinert).
 

Neue Beiträge

Zurück