Problem mit toDataURL() und Canvas

B

ByeBye 274568

Ich möchte gern eine mit canvas erzeugte und bereits angezeigte Grafik zusätzlich mit einer URL anbieten (letztlich ein Link, der beim Klicken auf die Grafik zur größeren Version führt). Ich möchte nicht umständlich mit windows/popups arbeiten, sondern die reine URL haben. Das Vorschaubild funktioniert problemlos und wird derzeit wie folgt erzeugt:

HTML:
<canvas id="image"></canvas>

var ct1 = document.getElementById("image").getContext("2d");
ct1.canvas.width = document.getElementById("image").offsetWidth;
ct1.canvas.height = document.getElementById("image").offsetHeight;
var Chart1  = new Chart(ct1).Line(lineChartData1,options);
Das Canvas-Element ist zusätzlich in einem DIV-Container untergebacht, weshalb hier nach offsetWidth und offsetHeight gefragt wird. Eine festgesetzte Grafik ist's wegen des Responsive-Designs nicht; es passt sich hervorragend der Größe an. Die entscheidende Generierung der Grafik erfolgt schließlich mit new Chart(ct1).Line(lineChartData1,options);. Wie auch immer, das läuft einwandfrei.

Um eine URL aus einem Canvas-Element zu erzeugen, gibt es toDataURL(), doch damit habe ich Probleme:
HTML:
var url = document.getElementById("image").toDataURL();
document.write(url);

Das aufgeführte Beispiel erzeugt eine URL und gibt sie beispielhaft als Text aus. Das funktioniert auch - zumindest teilweise: 2 arge Probleme habe ich damit:

  1. Die URL wird zwar angezeigt (auch die grafik mittels popup), enthält aber nichts, nur eine freie Fläche und nicht das eigentliche Bild.
  2. Ich möchte dem Canvas natürlich noch die Option geben, eine höhere Auflösung generieren zu lassen, wie ich es mit ct1.canvas.width und ct1.canvas.height beim eigentlichen Bild schon erledigt habe.

Also, was ist falsch im Code?
 
Die Frage wäre doch, was Dir toDataURL() ausgibt. Und natürlich, wie Du diesen Wert einbindest, damit Dir das Bild angezeigt wird.
 
Das hatte ich schon geschrieben: toDataURL() soll eine höhere Auflösung des "Bildes" anbieten, was mit den Options eigentlich schnell erledigt ist. Diese URL wird als simple Verlinkung auf dem Canvas angeboten.
 
Du hast meine Frage falsch interpretiert: ich möchte von Dir nicht wissen, was Du haben möchtest, sondern, was Du bekommst.
 
Hallo Quaese, besten Dank, ich denke, das ist schon mal ein sehr guter Ansatz, der uns auf den richtigen Pfad bringt. Ich habe Deine Version mal etwas minimiert und modifiziert, in dem ich u.a. nicht das img-src verändere, sondern den Link um das Canvas-Element herum. Das klappt auch. HREF wird verändert, doch auch hier wird nur die blanke und offenbar ungerenderte Grafik ausgegeben (ich hab's auch mit img-src ausprobiert, mit gleichem Ergebnis). Die leere bzw. lediglich transparente Grafik hat die exakte Größe des Originals.

HTML:
<a HREF="#" id="canvas_link">
<canvas id="canvas_id"></canvas>
</a>

var objCanvas = document.getElementById("canvas_id");
var objContext = objCanvas.getContext('2d'), Chart1;  

objContext.canvas.width = objCanvas.offsetWidth;
objContext.canvas.height = objCanvas.offsetHeight;  

var Chart1  = new Chart(objContext).Line(lineChartData1,options);    
  
document.getElementById("canvas_link").href = objCanvas.toDataURL();

Vielleicht liegt es daran, dass objCanvas (in der ersten und letzten Zeile) noch gar nichts gerendert hat? Schließlich muss Chart.js (was ich verwende) erstmal das Diagramm, was vermutlich erst in der Zeile mit var Chart1 = geschieht, erzeugen? Nur so eine wirre Idee. Aber einfach Chart1 statt objCanvas vor toDataURL() zu setzen, klappt auch nicht. Wäre ja zu schön gewesen ;-)
 
Wenn Dir in Deinem Canvas etwas angezeigt wird, dann ist es gerendert wurden, und somit auch mit toDataURL() abrufbar.
 
Das ist nur teilweise korrekt und hilft hier gerade überhaupt nicht weiter. Zunächst einmal funktioniert ja toDataURL(), wie schon geschrieben. Außerdem wird ja erst mit dieser Zeile

HTML:
var Chart1  = new Chart(objContext).Line(lineChartData1,options);

das eigentliche Diagramm mit den Werten aus lineChartData1 erzeugt. Vorher taucht das doch noch gar nicht auf. Also ja, es wird vorher irgendwas gerendert (ich vermute mal, einfach nur das Grundgerüst), aber nicht das fertige Bild.

Um Richtung Ziellösung zu blicken, muss möglicherweise das fertige Diagramm mit toDataURL() versehen werden und nicht vorher. Und bei diesem Punkt stehe ich auf dem Schlauch.
 
Noch einmal: toDataURL() verwandelt genau das, was man auf dem Canvas sieht in ein Base64-kodiertes Bild. Somit kann bei Dir das Problem nur deshalb auftreten, weil Du die Methode zu früh aufrufst. Insofern ist meine Aussage nicht nur teilweise korrekt.

Und auch wenn ich mich erneut wiederhole: es wäre sehr hilfreich, wenn wir etwas von Deinem Skript sehen könnten, so dass wir damit auch etwas anfangen können. Alles andere ist ein Herumraten.
 
Zurück