Viewports und Clipping

Viewports und Viewport-Koordinaten

Beim Erzeugen eines CanvasGI-Objekts (siehe Seite "CanvasGI - Skelettprogramm") wird zunächst die gesamte Zeichenfläche als "Current viewport" festgelegt (das Geräte-Koordinatensystem liegt in der linken oberen Ecke des Viewports). Mit der Funktion setcurrentviewport können ein beliebiges rechteckiges Teilgebiet der Zeichenfläche zum "Current viewport" erklärt und ein anderes Viewport-Koordinatensystem eingestellt werden.

Ein Viewport ist ein rechteckiger Teilbereich der Zeichenfläche, der

  • durch die Angabe der Geräte-Koordinaten seiner linken oberen Ecke (bezüglich der linken oberen Ecke der Zeichenfläche, "Upper left point") und
  • die Angabe seiner Breite und Höhe (ebenfalls in Geräte-Koordinaten) definiert wird.
  • Der Rechteck-Bereich des Viewports kann wahlweise die Ausgabe der nachfolgenden Zeichenaktionen begrenzen (Standard-Einstellung) und wird damit zum "Clipping-Bereich".
  • Für die CanvasGI-Funktionen, die mit Viewport-Koordinaten arbeiten, wird bei der Definition des Viewports eins von 5 möglichen Koordinatensystemen festgelegt.

Die Abbildung links zeigt die beiden Abmessungen (in Geräte-Koordinaten), mit denen der "Upper left point" PUL des Viewports festgelegt wird, und die beiden Abmessungen des Viewports. Diese vier Werte müssen als Argumente beim Aufruf von setcurrentviewport übergeben werden.

Das fünfte Argument, das setcurrentviewport übergeben werden kann (Typ des Viewport-Koordinatensystems), ist optional, weil für diesen Parameter der Default-Wert XYTOPLEFT (Koordinaten-Ursprung in der linken oberen Ecke des Viewports) vorgesehen ist.

Es stehen fünf Viewport-Koordinatensysteme zur Wahl, der Koordinaten-Ursprung liegt entweder in einer Ecke des Viewports oder in der Viewport-Mitte. In CanvasGI sind dafür sinnvolle Konstanten definiert. Die Abbildung rechts zeigt die Lage und die Richtung der Achsen für die Koordinatensysteme.

Der 6. Parameter beim Aufruf von

void setcurrentviewport (float pulx , float puly , float width , float height , integer cstype , boolean clip)

ist ebenfalls optional und gibt mit dem Wert true vor, dass die Zeichnung auf die Viewportgrenzen beschränkt werden soll ("Clipping", Standardeinstellung), bei false darf über die Viewportränder hinaus gezeichnet werden.

Beispiel-Programm

Das nachfolgend beschriebene Beispiel-Programm zeichnet in jeden Viewport eine "Rosette" (nebenstehendes Bild, gleichmäßig über einen Kreis verteilte Punkte werden so miteinander verbunden, dass von jedem Punkt zu jedem anderen eine gerade Linie existiert, der Kreis selbst wird nicht gezeichnet).

In zwei Zeilen werden jeweils vier Viewports mit der gleichen Zeichnung und gleichen CanvasGI-Befehlen gefüllt, dabei ist das Verhältnis des Kreisdurchmessers zur kleineren Viewport-Abmessung in den Viewports der oberen Zeile kleiner als 1, so dass die Zeichnungen in die Viewports "passen", in der unteren Viewportzeile ist dieses Verhältnis größer als 1, so dass das Clipping an den Viewport-Rändern deutlich wird.

Im Body-Teil der HTML-Datei wird der Canvas-Bereich mit der id="canvas" erzeugt, die Zeichenaktion wird gestart durch eine Anweisung im Body-Tag:

<body onLoad="init();">

In der JavaScript-Funktion init wird das cavasGI-Objekt erzeugt und einer global vereinbarten Variablen gi zugewiesen, damit es in allen anderen Funktionen verfügbar ist:

  var clippingon = true ;
  var gi ;

  function init() {
     gi = new canvasGI ("canvas") ;              // ... definiert ein canvasGI-Objekt
     draw () ;
  }  

Im zweiten Schritt startet init die Funktion draw, in der die Viewports definiert und alle Zeichenaktionen ausgeführt werden (die farbig gekennzeichneten Bereiche werden weiter unten erläutert):

  function draw() {

     var nViewpx = 4 , nViewpy = 2 , nPoints = 15 ;
     var QuotDiamLowDist = 0.9 ;
     var Radius , ix , iy , i , j , xs , ys , dPhi ;

     var canwidth  = gi.getcanvaswidth  () ;
     var canheight = gi.getcanvasheight () ;

     gi.clearcanvas ("silver") ;

     for (iy = 0 ; iy < nViewpy ; iy++) {
        for (ix = 0 ; ix < nViewpx ; ix++) {
           gi.setcurrentviewport (canwidth * ix / nViewpx , canheight * iy / nViewpy ,
                                  canwidth / nViewpx      , canheight / nViewpy      , gi.XYCENTER , clippingon) ;
              // ... definiert den "Current viewport" mit einem (Pixel-)Viewport-
              //     Koordinatensystem in Viewportmitte

           gi.beginpath () ;                      // ... startet einen "Path"

           if (canwidth / nViewpx > canheight / nViewpy) { Radius = canheight / nViewpy ; }
           else                                          { Radius = canwidth  / nViewpx ; }

           Radius = Radius * QuotDiamLowDist / 2 ;
           dPhi = Math.PI * 2. / nPoints ;           // 2*pi/nPoints

           for (i = 0 ; i < nPoints ; i++) {
              xs = Radius * Math.cos(dPhi * i) ;
              ys = Radius * Math.sin(dPhi * i) ;
              for (j = i + 1 ; j < nPoints ; j++) {
                 gi.vline (xs , ys  , Radius * Math.cos (dPhi * j) , Radius * Math.sin(dPhi * j)) ;
              }
           }

           gi.stroke () ;                         // ... zeichnet den definierten "Path"
        }                                         // ... Ende einer Reihe
        QuotDiamLowDist = 1.5 ;                   // ... vergroessert Radius fuer untere Reihe
     }                                            // ... Ende aller Reihen
  }                                               // ... Ende function draw  

Die komplette HTML-Datei c_viewport.html kann in einem neuen Browser-Fenster ausgeführt werden.

Sie enthält einen Button, mit dem man das Clipping ausschalten kann (globale Variable clippingon wird auf false) gesetzt. Danach zeichnen die Viewports der unteren Reihe über ihre Grenzen hinaus (an den Grenzen der Canvas-Zeichenfläche wird allerdings in jedem Fall "geclippt").

Weiterlesen

Folgende Seiten werden als Einführung in die Benutzung des CanvasGI empfohlen: