Chimicherrychanga

HTML5: Zeichnen auf Canvas

Informatik von Seba

Screenshot Canvas-Test

Da ich es unter Umständen nochmal brauchen werde, habe ich mich mit dem HTML5-Element canvas beschäftigt und wie man mit Javascript darauf arbeitet. Um ein wenig die Motivation daran zu heben, beschloss ich, wieder etwas zu zeichen – wie damals Kyubey mit CSS.

Die Canvas-Demo sollte in jedem aktuellen Browser bei aktiviertem Javascript funktionieren.

Wer auch daran Interesse hat den Umgang mit Canvas zu lernen, dem seien Dive Into HTML5 und das Mozilla Developer Network nahegelegt.

Vollbild

canvas {
	height: 100%;
	width: 100%;
}

Nope! Das verzerrt nur das Bild und es wird unförmig und verwaschen. Möchte man kein Vollbild, kann man Pixel-Angaben nehmen. Ansonsten macht man es dynamisch mit Javascript und weißt dem <canvas> die Fensterhöhe und -breite zu:

canv = document.getElementById( "my_canvas" );
canv.height = window.innerHeight;
canv.width = window.innerWidth;

Wenn man die Fenstergröße ändert, muss man allerdings nochmal die Seite aktualisieren, damit sich der Inhalt auch anpasst. Ließe sich bestimmt auch über Javascript machen.

Das Auge

Besonders problematisch war das Auge. Erst einmal ist die zugrundeliegende Form eine Ellipse, aber mit den gegebenen Funktionen lassen sich nur Bögen und Kreise zeichnen. Nach misslungenen Versuchen mit scale() um den Kreis wie gewünscht zu verzerren, habe ich schließlich diesen Algorithmus genommen, der Bézierkurven verwendet.

Nächste Hürde: Wie kann ich dafür sorgen, dass Iris und Pupille am Rand der weißen Ellipse abgeschnitten werden? Order um auf mein verbliebenes Wissen aus Computergrafik zurück­zugreifen: Wie setze ich hier Clipping ein?

// Eye
context.beginPath();
context.save();
context.rotate( Math.PI / 180 * 12 );
context.translate( 62, -69 );
cadraw.ellipse( [263, 398], [403, 213] );
context.restore();

// Start clipping inside eye
context.save();
context.clip();

// … Draw ALL THE inner-eye stuff! …

// End clipping inside eye
context.restore();

Nachdem man den Pfad für das Auge festgelegt hat, kann man mit clip() diesen als Grenze festlegen. Damit die späteren Zeichnungen davon nicht betroffen sind, speichert man vorher mit save() den Zustand. Nachdem das Augeninnere gezeichnet ist, stellt man den unge-clippten Zustand mit restore() wieder her.


Die nächste Zeichnung könnte ich ja dann mit WebGL machen. Hoffentlich wird es auch in Opera bis dahin unterstützt. Mann, Mann, Mann, die verwendete Technik wird dann aber auch von Mal zu Mal aufwendiger.

5 Kommentare

  1. avatar B
    wow, 20% cooler geworden deine Seite^^
  2. avatar Andrej
    My Little Pony!
    YAAAAY!
  3. avatar hubs
    The Sriacha Rooster rendered in HTML5 Canvas:

    http://www.artifacting.com/blog/2011/08/25/sriracha-rooster-drawn-entirely-in-html5-canvas-2/
  4. avatar Twaldigas
    Da hat er wieder zugeschlagen. ^^
    Abgesehen vom Motiv, schöne Arbeit. Ich mag canvas und habe auch schon mit experimentiert. Bietet halt extrem viele Möglichkeiten, was die Formen angeht und es lässt sich damit halt gut zeichnen. Aber es ist halt auch JavaScript und ich habe mich mit dem Einstieg extrem schwer getan. Wie du, wenn ich mich an den tweet richtig erinnere. ;)

    Gruß Twaldigas
  5. avatar Seba
    @Twaldigas:
    Yep, mit „reinem“ Javascript – ohne jQuery als Framework dazwischen – habe ich bisher noch nicht allzu viel Kontakt gehabt. Das sollte ich vielleicht mal ändern, wenn man bedenkt, wie sehr es Anwendung findet und was man sogar eher Unterwartetes mit anstellen kann, z.B. MP3s decodieren und PDFs generieren.

Und jetzt du

Do not fill in these four fields:







Name, Mail und URL sind freiwillige Angaben. E-Mail-Adressen werden weder veröffentlicht noch weitergegeben. Verwendbares HTML: <a href=""> <abbr title=""> <blockquote> <cite> <code> <del> <i> <em> <b> <strong>