JavaScript Codeschnipsel: Farbwechsel im Sonnenlauf

Der Code

Der Code lautet wie folgt:

function jn_bgcolorBySunYear(r, g, b) {
	var r = typeof r !== 'undefined' ? r : false;
	var g = typeof g !== 'undefined' ? g : false;
	var b = typeof b !== 'undefined' ? b : false;

	// Ausgangswert für die Berechnungen ist die Wintersonnenwende im Jahr 2010
	var base = new Date(2010, 11, 22, 0, 38, 0, 0); // 22.12.2010 00:38
	// Länge eines Sonnenjahres (derzeitiges approx. Mittel) in Millisekunden
	var sunYear = 31556926080; // = 365.2422 * 1000*60*60*24
	
	// aktuelles Datum ermitteln
	var date = new Date();
	
	// Abstand vom Ausgangswert in ganzen Jahren ermitteln
	var offset = date.getFullYear() - base.getFullYear(); // Delta der Jahreszahlen
					
	// Datum der nächsten Wintersonnenwende berechnen
	var sunDate = base.valueOf() + offset * sunYear;
	// Anpassung um ein Sonnenjahr, wenn das aktuelle Datum bereits nach der Wintersonnenwende liegt
	if (date.valueOf() > sunDate) sunDate += sunYear;
	
	// Berechnung des Fortschritts im Sonnenjahr, wobei ein Kreis beschrieben wird,
	// also von 0 über 1 zurück zur 0
	var progress = 255 - Math.round(255 * Math.abs(2*(sunDate - date.valueOf() - sunYear/2))/sunYear);				

	// CSS Code austauschen
	if (r === false || g === false || b === false) {
		// bei fehlender oder unvollständiger Farbvorgabe
		// Umwandeln des Werts in eine Hexadezimalzahl
		var hexCode = progress.toString(16);
		document.body.style.backgroundColor = '#' + hexCode + hexCode + hexCode;
		if (hexCode.length < 2) hexCode = '0' + hexCode;
	} else
		// mit Farbvorgabe
		document.body.style.backgroundColor = 'rgba(' + r + ',' + g + ',' + b + ',' + progress / 255 + ')';
}

Aufgerufen wird der JavaScript Code nun an einer beliebigen Stelle auf der Webseite mittels jn_bgcolorBySunYear();
Da der Farbcode sich nur einmal alle ca. 17 Stunden verändert, ist hier kein zyklischer Aufruf sinnvoll.

Komprimiert sieht der Code dann wie folgt aus:

function jn_bgcolorBySunYear(e,o,a){e=void 0!==e&&e,o=void 0!==o&&o,a=void 0!==a&&a;var l=new Date(2010,11,22,0,38,0,0),r=31556926080,t=new Date,n=t.getFullYear()-l.getFullYear(),u=l.valueOf()+n*r;t.valueOf()>u&&(u+=r);var d=255-Math.round(255*Math.abs(2*(u-t.valueOf()-r/2))/r);if(!1===e||!1===o||!1===a){var v=d.toString(16);document.body.style.backgroundColor="#"+v+v+v,v.length<2&&(v="0"+v)}else document.body.style.backgroundColor="rgba("+e+","+o+","+a+","+d/255+")"}

Wem das Grau übrigens zu grau ist und lieber einen Farbton rollieren lassen möchte, übergibt der Funktion die drei Farbwerte (rot, grün und blau) des Grundtons als Dezimalzahl, also beispielsweise jn_bgcolorBySunYear(73, 2, 8);

Beitrag vorlesen lassen

11 Kommentare

  1. Hallo Michael L. Jaegers,

    Ich möchte gerne dein code Farbwechsel über den Tag
    für ein noch nicht vorhanden Gezeiten Widget auf meiner Website einsetzen allerdings weis ich nicht genau wie ich Ihm implementieren soll.

    Muss ich den kompletten Code in Html einbinden oder kann ich das über ein externer Javascript Datei machen und wie rufe ich den Code dann in Html auf. Kannst du mir ein Code-Kombi beispiel von Javascript und HTML vorgeben??

    vielen lieben Dank!

    Martijn Walk

    1. Hallo Martijn,

      der JavaScript Code kann innerhalb der <script></script> Tags im HTML Code eingebettet werden, oder als separate Datei abgelegt und dann im HTML Code mit <script src=dateinama.js></script> eingebunden werden, wobei „dateiname.js“ durch den Namen der Datei ersetzt werden muss, die den JavaScript Code beinhaltet. Ich empfehle die letztere Variante, besonders dann, wenn die Funktion auf mehreren Seiten eingebunden werden soll.

      Anschließend kann die Funktion dann auf der Seite mit z. B. <script>jn_bgcolorBySunYear(73, 2, 8);</script> im HTML Code aufgerufen werden.

      Schönen Gruß,
      Michael

  2. Hallo Herr Jaegers,

    irgendwie klappt es nicht mit dem einbinden.
    ich habe das Script extern eingebunden und rufe das Script wie gesagt im Html auf.
    der Body habe ich im CSS mit eine Farbe #ffffff angegeben.

    Eine andere Frage wäre, kann ich das Script auch klassifizieren um die Hintergrundfarbe einen Container den Farbwechsel zu verpassen. Das würde den Zweck für meine Vorstellung erfüllen.

    1. Hallo Herr Walk,

      die Angaben reichen nun nicht für eine geeignete Ferndiagnose, da müsste ich schon eine URL haben, auf der das Script eingebunden sein sollte.

      Mit minimalen JavaScript Kenntnissen kann das Script auch dergestalt angepasst werden, dass andere HTML Elemente, z. B. die Hintergrundfarbe eines Containers, verändert wird.

      So findet sich die entscheidende Stelle im Code an zwei mal mit

      document.body.style.backgroundColor = ...

      Mit

      document.getElementById('id').style.backgroundColor = ...

      und id als Id Attribut des gewünschten Objekts, sollte es dann auch funktionieren.

      Schönen Gruß,

      Michael Jaegers

      1. Hallo Herr Jaegers,

        ich habe das unfertige Widget auf meine Website unter Sitemap> test eingebunden aber das aufrufscript im Html heraus genommen da ich selber noch herum probiere. Ich möchte lediglich das der hellblaue Hintergrund in dunkelblau nach verlauf des Tages verändert, dafür müsste class „colorchange“ angesprochen werden.

        Ich hoffe ich mache Ihnen nicht zuviel mühe und wäre sehr dankbar wenn Sie mir einige Instruktionen geben könnten.

        besten Dank Martijn Walk

  3. ah erleuchtung das Script tut was, nach dem ich den Code für ID eingegeben habe und das Ausführscript mit true und eine Farbe im Javascript eingefügt habe. Jetzt schauen welche Werte ich im Javascript sonnst noch ändern muss um von hellblau nach dunkelblau und zuruck zu gehen.

    Vielleicht können Sie mir an der Stelle weiter helfen..

    Liebe grüße,

    Martijn Walk

    1. Hallo Herr Walk,

      um eine andere Farbe für den Farbverlauf zu wählen, sollte es reichen den RGB Farbcode beim Aufruf der Funktion mit anzugeben. Also etwa wie folgt:

      jn_bgcolorByDayTime(false, 0, 51, 102)

      wobei 0, 51 und 102 die Dezimalwerte für rot, grün und blau sind. Das false als erster Parameter sorgt dafür, dass sich die Farbe nicht alle zweieinhalb Minuten automatisch verändert, wie oben beschrieben. Es muss also an der eigentlichen Funktion nichts verändert werden.

      Schönen Gruß,

      Michael Jaegers

  4. Moin Herr Jaeger,

    es klappt!! falls ich das grau was um 00:00 komplett ist in ein Dunkelblau haben möchte welchen Parametern muss ich dann ändern? der Farbe im Css ID wird komplett überschrieben vom Javascript und hat inprinzip keine Funktion mehr bzw. lediglich als Fallback-Farbe.

    ist es dann notwendig alle 255 Werte auf z.B. 40,57,79 zu ändern und oder /auch der letzte Parameter der im Originalscript mit den Wert: 169412 (ein sattes grün wie ich gesehen habe), ändern.

    also nachts den Wert 40,57,79 und tagsüber den Wert 139,202,243

    Ich freue mich auf ein letzten Antwort und bedanke mich herzlichst.

    1. Hallo Herr Walk,

      das Skript rolliert – so wie es aktuell programmiert ist – über eine (!) Farbe, verändert dann aber die Farbsättigung von 0 bis 100% und zurück.

      Möchte man, wie ich Ihrem Kommentar entnehme, über zwei unterschiedliche Farben (40, 57, 79, bzw. 139, 202, 243) rollieren, ist eine andere Berechnung erforderlich, bzw. muss die Berechnung über alle Farbwerte (plus ggf. die Sättigung) erfolgen. Siehe hierzu auch den Wikipediabeitrag zum Farbgradienten (https://de.wikipedia.org/wiki/Farbgradient).

      Der lineare (und ggf. nicht ganz optimale Ansatz) lässt sich wohl hiermit abbilden:

      &lt;code&gt;function gradient(color1, color2, weight) {
      var w1 = weight;
      var w2 = 1 – w1;
      return [
      Math.round(color1[0] * w1 + color2[0] * w2),
      Math.round(color1[1] * w1 + color2[1] * w2),
      Math.round(color1[2] * w1 + color2[2] * w2)
      ];
      }&lt;/code&gt;

      color1 und color2 sind jeweils Felder mit den drei Farbwerten für Start und Ende.
      weight beinhaltet den Faktor für den Fortschritt im Tag, also Mitternacht 0, Mittag 1; dazwischen jeweils anteilig abgestuft.
      Als Ergebnis liefert die Funktion dann wiederum ein Feld mit den drei Werten für R, G und B.

      Für den Nicht-linearen Verlauf berechnen sich dann die einzelnen Werte in der Funktion mit

      &lt;code&gt;Math.round(Math.sqrt(Math.pow(color1[i], 2) * w1 + Math.pow(color2[i], 2) * w2))&lt;/code&gt;

      mit i=0 bis 2.

      Ohne dies nun getestet zu haben, sollte der Code dann insgesamt wie folgt aussehen:

      &lt;code&gt;function jn_bgcolorByDayTime(loop, r1, g1, b1, r2, g2, b2) {
      var r1 = typeof r1 !== ‚undefined‘ ? r1 : false;
      var g1 = typeof g1 !== ‚undefined‘ ? g1 : false;
      var b1 = typeof b1 !== ‚undefined‘ ? b1 : false;

      var r2 = typeof r2 !== ‚undefined‘ ? r2 : false;
      var g2 = typeof g2 !== ‚undefined‘ ? g2 : false;
      var b2 = typeof b2 !== ‚undefined‘ ? b2 : false;

      // Länge eines Tages in Millisekunden
      var dayTime = 86400000; // = 24*60*60*1000

      // aktuelles Datum ermitteln
      var date = new Date();

      // Berechnung des Fortschritts am Tag, wobei ein Kreis beschrieben wird,
      // also von 0 über 1 zurück zur 0
      var progress = 255 – Math.round(255 * Math.abs(2*(1000 * (date.getSeconds() + 60 * (date.getMinutes() + 60 * date.getHours())) + date.getMilliseconds() – dayTime/2))/dayTime);

      // CSS Code austauschen
      if (r1 === false || g1 === false || b1 === false) {
      // bei fehlender oder unvollständiger Farbvorgabe
      // Umwandeln des Werts in eine Hexadezimalzahl
      var hexCode = progress.toString(16);
      if (hexCode.length &lt; 2) hexCode = ‚0‘ + hexCode;
      document.body.style.backgroundColor = ‚#‘ + hexCode + hexCode + hexCode;
      } else if (r2 === false || g2 === false || b2 === false) {
      // mit Startfarbvorgabe, rollieren über Sättigung
      document.body.style.backgroundColor = ‚rgba(‚ + r1 + ‚,‘ + g1 + ‚,‘ + b1 + ‚,‘ + progress / 255 + ‚)‘;
      } else {
      // mit Start- und Zielfarbvorgabe, rollieren über den Gradienten zwischen den beiden Farben
      document.body.style.backgroundColor = ‚rgba(‚
      + Math.round(Math.sqrt(Math.pow(r1, 2) * w1 + Math.pow(r2, 2) * w2)) + ‚,‘
      + Math.round(Math.sqrt(Math.pow(g1, 2) * w1 + Math.pow(g2, 2) * w2)) + ‚,‘
      + Math.round(Math.sqrt(Math.pow(b1, 2) * w1 + Math.pow(b2, 2) * w2)) + ‚,255)‘;
      }

      if (typeof loop !== ‚undefined‘ &amp;&amp; loop)
      window.setTimeout(‚jn_bgcolorByDayTime(true,‘ + r1 + ‚,‘ + g1 + ‚,‘ + b1 + ‚,‘ + r2 + ‚,‘ + g2 + ‚,‘ + b2 + ‚)‘, 169412);
      }&lt;/code&gt;

      Der Funktionsaufruf lautet dann jn_bgcolorByDayTime(loop, r1, g1, b1, r2, g2, b2), wobei r1, g1 und b1 die Werte für die erste und r2, g2 und b2 die Farbwerte für die zweite Farbe darstellen.

      Schönen Gruß,
      Michael Jaegers

Kommentar hinterlassen

Nutze dieses Kommentarfeld um deine Meinung oder Ergänzung zu diesem Beitrag kundzutun. Verhalte dich bitte respektvoll und höflich! Kommentare werden vor der Veröffentlichung in der Regel moderiert und bei Verstößen gegen geltendes Recht, die guten Sitten, fehlendem Bezug oder missbräuchlicher Verwendung nicht freigegeben oder gelöscht.
Über die Angabe deines Namens, deiner E-Mail Adresse und deiner Webseite freuen wir uns, doch diese Felder sind optional. Deine E-Mail Adresse wird dabei zu keinem Zeitpunkt veröffentlicht.

Um mit dem Betreiber dieser Seite nicht-öffentlich in Kontakt zu treten, nutze die Möglichkeiten im Impressum.