News CONSUS OKAS Fachartikel Spiele Impressum
 
Canvas - Spakling Stars
In diesem Artikel wird beschrieben, wie man mit dem HTML 5.0 Canvas Element einen funkelnden Sternenhintergrund erschafft.
 
Zunächst erschaffen wir eine Funktion, die vor jedem Frame der Animation den Canvas komplett schwarz macht, damit es möglich ist, jeweils die Sterne mit der neuen Helligkeit darauf zu zeichnen (und Resultate auch sichtbar sind). Wir übergeben der Funktion dazu das Canvas Objekt. Innerhalb der Funktion wird der vorherige fillStyle des Objekts am Ende wiederhergestellt, das ist für diese Anwendung nicht erforderlich, aber die Funktion hat sich schon öfter als nützlich erwiesen mit diesem Feature, deshalb habe ich mich dazu entschlossen, sie nicht abzuändern.
 1:
 2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
10:
11:
function canvas_black_scr(canvas){
  var tmp_color = canvas.fillStyle;
  canvas.fillStyle = "rgba(0,0,0,1)";
  canvas.fillRect(
    0,
    0,
    canvas.canvas.width,
    canvas.canvas.height
  );
  canvas.fillStyle = tmp_color;
}
Nun brauchen wir eine Klasse für unsere Sterne. An Attributen interessiert natürlich die Position, also die X und Y Koordinate auf dem Canvas, die Farbe, da nicht gewollt ist, dass alle Sterne rein weis sind, sowie ein Wert, shade, für den momentanen Helligkeitsstand. Des weiteren die Größe des Sterns auch hier für die Vielfalt, einen Boolean für Sparkle, da evt. nicht alle Sterne funkeln sollen und um das Thema funkeln abzuschließen, eine Richtung, also wird der Stern heller oder dunkler, und einen Wert für die Helligkeits Zu- und Abnahme.
Ich habe die Steps der Helligkeit auf 0.05 voreingestellt, was ein weiches faden zur Folge hat, es ist natürlich auch möglich dort noch einen Math.random() Faktor einzufügen, um bei jedem Stern den Fadevorgang unterschiedlich zu gestalten.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
function stars_stars(){
	this.x = 0;
	this.y = 0;
	this.shade = 1;
	this.color = 0;
	this.size = 0;
	this.sparkle = false;
	this.sparkle_dir = false;
	this.sparkle_steps = 0.05;
}
Als nächstes wird eine Funktion benötigt, die einen Array mit den Sternenobjekten füllt und diese Sterne mit den nötigen Werten versieht. übergeben werden der Funktion die Variablen anz, für die Anzahl der Sterne, width und height, für die Abmaße des Canvas, und range, was die maximal Größe der Sterne festsetzt.
Ein paar Worte zu den Farben, wie bereits erwähnt ist nicht gewollt, dass alle Sterne die gleiche Farbe haben, daher wird der Wert mit Math.random() erzeugt. Allerdings sehen zu extreme Farben nicht besonders schön aus, daher habe ich die möglichen Werte der 3 Farbkomponenten auf 220 - 255 festgesetzt. Der erzeugte rgba String ist nicht vollständig, es fehlt der opacity Wert und die abschließende Klammer, dies wird erst in der Animation komplettiert, da der opacity Wert erst noch berechnet werden muss.
Die if Bedingung legt fest, wie viele der Sterne funkeln, in diesem Beispiel tun dies alle vorhandenen, da Math.random() immer größer gleich 0 ist. Hier lässt sich leicht die Anzahl auf z.B. 50% regeln wenn die Bedingung zu größer gleich 0.5 wird.
Die auskommentierte Stelle innerhalb der if Klausel ist für das bereits erwähnte zufällige generieren der steps gedacht. Jeder kann dort mal ein wenig mit den Werten herum probieren.
Am Ende gibt die Funktion den Fertigen Sternen Array zurück.
 1:
 2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
function stars_generate(anz,width,height,range){
  if (typeof range == "undefined") range = 5;
  var stars = new Array(anz);
  for (var i = 0; i < anz; i++){
    stars[i] = new stars_stars();
    stars[i].x = Math.floor(Math.random() * width);
    stars[i].y = Math.floor(Math.random() * height);
    var red = Math.floor(Math.random() * (256 - 200)) + 200;
    var green = Math.floor(Math.random() * (256 - 200)) + 200;
    var blue = Math.floor(Math.random() * (256 - 200)) + 200;
    stars[i].color = "rgba(" + red + ";
    stars[i].color += "," + green + "," + blue + ",";
    stars[i].size = Math.floor(Math.random() * range);
    if (Math.random() >= 0){
      stars[i].sparkle = true;
      stars[i].shade = (Math.floor(Math.random() * 10)) / 10;
      //stars[i].sparkle_steps = Math.random() ;
    }
  }
  return stars;
}
Jetzt ist alle Vorarbeit erledigt und wir können uns der Animation zuwenden. Als aller erstes wird überprüft ob uns ein Array mit Sternen zur Verfügung steht, wenn nicht wird er generiert. Vor jedem Durchgang muss der Canvas wieder Schwarz gemacht werden, was mit dem Aufruf unserer canvas_black_scr() Funktion erledigt ist.
Nun kann der Array durchlaufen werden. Bei jedem Stern wird überprüft ob er funkeln soll und entsprechend die Berechnung gestartet. Zu guter Letzt wird der rgba String vervollständigt und die Sterne auf den Canvas gemalt, mit Hilfe der arc() Funktion.
Der setTimeout Aufruf startet den nächsten Durchlauf, auch hier kann noch mit der Zeit experimentiert werden.
 1:
 2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
function stars_draw(canvas,anz,range){
  if (typeof stars == "undefined"){
    stars = stars_generate(
      anz,
      canvas.canvas.width,
      canvas.canvas.height,
      range
    );
  }
  canvas_black_scr(canvas);
  for (var i = 0; i < stars.length; i++){
    if (stars[i].sparkle == true){
      if (stars[i].sparkle_dir == false){
        stars[i].shade -= stars[i].sparkle_steps;
        if (stars[i].shade <= 0){
          stars[i].shade = 0;
          stars[i].sparkle_dir = true;
        }
      } else {
        stars[i].shade += stars[i].sparkle_steps;
        if (stars[i].shade >= 1){
          stars[i].shade = 1;
          stars[i].sparkle_dir = false;
        }
      }
    }
    canvas.fillStyle = stars[i].color + stars[i].shade + ")";
    canvas.beginPath();
    canvas.arc(
      stars[i].x,
      stars[i].y,
      stars[i].size,
      0,
      Math.PI * 2, true
    );
    canvas.closePath();
    canvas.fill();
  }
  setTimeout(function(){stars_draw(canvas,anz,range);},100);
}
Ich bedanke mich für das Lesen meines Artikels und wie immer gilt:
Bei Fragen, Wünschen, Anregungen oder Verbesserungen dieses Artikels kann man uns jederzeit eine Mail schicken.

JW
 
Aktuelles:
  - new Beam Video
Projekte:
  - CGE Consus Game Engine
- OKAS unsere Webhosting Software
Social: