Magisches fillRect() mit Javascript

Freitag, 21. September, 2012

Ich schreibe gerade an einem HTML5 Audioplayer. Bevor jemand sagt: davon gibt es ja bereits hunderte - such’ doch einfach einen davon aus… Nein, der Player wird zu einem späteren Zeitpunkt beleuchtet. Das sollte doch nur ein Aufhänger sein.
In einem Player braucht es einen Fortschrittsbalken. Je nach Abspielposition soll da ein Canvas mit der fillRect Funktion bemalt werden. Canvas … das ist eine Zeichenfläche im Webbrowser auf der man Bildpunkte manipulieren kann und von Microsoft im Internet Explorer 6 eingeführt wurde. In HTML5 wurde es offiziell und endlich in allen neuen Webbrowsern verfügbar gemacht.

<canvas id="progresscanvas"></canvas>

Per CSS wurde Breite und Höhe des Canvas mit 10px x 220px gesetzt.

Eine der Zeichenfunktionen ist fillRect. Damit kann man ein ausgefülltes Rechteck zeichnen. Dazu gibt man als Parameter x- und y- Koordinaten des Start- und Endpunktes an.

Mein Javascript Snippet:

var canvas=document.getElementById('progresscanvas');
if (canvas.getContext) {
  var ctx = canvas.getContext("2d");
  ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
  var iAlpha=0.05 + oAudio.currentTime / oAudio.duration /10*1;
  ctx.fillStyle = "rgba(0,0,0, "+iAlpha+")";
  var fWidth = Math.round((oAudio.currentTime / oAudio.duration) * (canvas.clientWidth));
  if (fWidth > 0) {
    ctx.fillRect(0, 0, fWidth, canvas.clientHeight);
  }
}

Irgendwie kam allerdings nicht das heraus, was ich meinte, was entstehen müsste. Mit einem console.log geprüft, welche Parameter im “ctx.fillRect(0, 0, fWidth, canvas.clientHeight);” landen - hier kommt sogar das Richtige:

2012-09-21-fillrect.png

Wenn man den Player anschaut: mein Song ist kurz vor dem Ende. Unten in der Konsolenausgabe ist der letzte fillRect Aufruf drin - es soll das Canvas gefüllt werden von links oben (0,0) bis (10, 215) - javascript-seitig ist alles korrekt. Nur das Ergebnis ist im Webbrowser nicht: hier ist nur ein 2 Pixel hoher und 155 Pixel breiter Balken. Der Fortschrittsbalken an sich funktioniert, aber die Breite wird mit einem ominösen Faktor skaliert.

Das Ganze habe ich mit verschiedenen Browsern getestet: Firefox, IE9 und Chrome verhalten sich gleich falsch.

Der Trick besteht darin: im HTML muss ich im Canvas bereits die korrekte Grösse angeben.
Statt

<canvas id="progresscanvas"></canvas>

nun

<canvas id="progresscanvas" width="220" height="10"></canvas>

… und schon geht es mit dem fillRect.

Kommentar hinzufügen

Die Felder Name und Kommentar sind Pflichtfelder.