NEWS
[gelöst]animierter Schnee - mir fehlt der letzte Gedanke
-
Also ich habe folgendes Skript:
! ////////////////////////////////////////////////////////////////////////
! // SnowFlakes-Script 2017, Dominik Scholz / go4u.de Webdesign
! ////////////////////////////////////////////////////////////////////////
! var snowflakes = {
! ///////////////////////////// configuration ////////////////////////////
! // amout of flakes
! _amount: 40,
! // random colors
! _color: ['#AAAACC', '#DDDDFF', '#CCCCDD', '#F3F3F3', '#F0FFFF'],
! // random fonts
! _type: ['Arial Black', 'Arial Narrow', 'Times', 'Comic Sans MS'],
! // char used for flake
! _flakeChar: '*',
! // speed of flakes
! _speed: .05,
! // minimum flake font size
! _minSize: 8,
! // maximum flake font size
! _maxSize: 22,
! // horizontal drift
! _drift: 15,
! // zIndex of flakes
! _zIndex: 20000,
! ///////////////////////////// private vars /////////////////////////////
! _flakes: [],
! _bodyWidth: 0,
! _bodyHeight: 0,
! _range: null,
! _count: 0,
! _lastInterval: 0,
! ////////////////////////////// functions ///////////////////////////////
! // init snow
! init: function()
! {
! this._addEventListener(window, 'resize', function() { return snowflakes.resize.apply(snowflakes); });
! this._addEventListener(window, 'load', function() { return snowflakes.start.apply(snowflakes); });
! },
! // add an event listener
! _addEventListener: function(el, name, handler)
! {
! if (el.addEventListener)
! el.addEventListener(name, handler, false);
! else if (el.attachEvent)
! el.attachEvent('on' + name, handler);
! },
! // start snow
! start: function()
! {
! // calculate range
! this._range = this._maxSize - this._minSize;
! // init window size
! this.resize();
! // add new flakes
! while (this._amount > this._flakes.length)
! this._createFlake(this._flakes.length);
! // start to move snow
! this._animFn = function() {snowflakes._move();};
! this._lastInterval = this._time();
! requestAnimFrame(snowflakes._animFn);
! },
! // get current time
! _time: function()
! {
! return +new Date();
! },
! // return a random integer
! _randomInt: function(value)
! {
! return Math.floor(
! Math.random() * value
! );
! },
! // return a random array element
! _randomArray: function(arr)
! {
! return arr[
! Math.floor(
! Math.random() * (arr.length)
! )
! ];
! },
! // creates a new snowflake
! createFlake: function(i)
! {
! var newEl = !this.flakes,
! el, f;
! if (newEl)
! {
! // create new dom el
! el = document.createElement('div');
! el.style.position = 'absolute';
! el.style.zIndex = this._zIndex;
! el.innerHTML = this._flakeChar;
! f = {
! el: el,
! x: 0,
! y: 0,
! size: 0,
! count: 0
! };
! this._flakes _= f;
! document.getElementsByTagName('body')[0].appendChild(el);
! }
! else
! {
! // use existing dom el
! f = this.flakes;
! el = f.el;
! }
! // init flake
! el.style.left = '0px';
! el.style.top = '-' + this._maxSize + 'px';
! el.style.color = this._randomArray(this._color);
! el.style.family = this._randomArray(this._type);
! el.style.fontSize = (this._randomInt(this._range) + this._minSize) + 'px';
! // create flake object
! f.x = this._randomInt(this._bodyWidth - this._drift - this._maxSize - 3) + this._drift + 1;
! f.y = -this._maxSize - this._randomInt(this._bodyHeight);
! f.size = this._randomInt(this._range) + this._minSize;
! f.count = this._randomInt(10000);
! },
! // move existing flakes
! _move: function()
! {
! requestAnimFrame(snowflakes._animFn);
! // calculate movement factor
! var dif = this._time() - this._lastInterval,
! l = this._flakes.length,
! d = dif * this._speed * this._maxSize,
! i, flake, flakeDiv;
! this._lastInterval = this._time();
! this._count += dif * this.speed / 20;
! for (i = 0; i < l; i++)
! {
! flake = this.flakes;
! flake.y += d / flake.size;
! // restart existing flake
! if (flake.y + flake.size >= this._bodyHeight)
! {
! this._createFlake(i);
! continue;
! }
! flake.el.style.left = Math.floor(flake.x + Math.sin(flake.count + this._count) * this._drift) + 'px';
! flake.el.style.top = Math.floor(flake.y) + 'px';
! }
! },
! // calculate new positions for all flakes
! resize: function()
! {
! // save old width
! var oldWidth = this._bodyWidth;
! // get new width and height
! this._bodyWidth = this.getWindowWidth() - this.maxSize;
! this.bodyHeight = this.getWindowHeight() - this.maxSize;
! // calculate correction ratio
! var ratio = this.bodyWidth / oldWidth;
! // for all flakes
! for (var i = 0, l = this.flakes.length, flake; i < l; i++)
! {
! flake = this.flakes;
! // do width correction
! flake.x *= ratio;
! // restart existing flake
! if ((flake.y + flake.size) >= this.bodyHeight)
! this.createFlake(i);
! }
! },
! // get window width
! getWindowWidth: function()
! {
! var w = Math.max(self.innerWidth || 0, window.innerWidth || 0);
! if (document.documentElement)
! w = Math.max(w, document.documentElement.clientWidth || 0);
! if (document.body)
! {
! w = Math.max(w, document.body.clientWidth || 0);
! w = Math.max(w, document.body.scrollWidth || 0);
! w = Math.max(w, document.body.offsetWidth || 0);
! }
! return w;
! },
! // get window height
! getWindowHeight: function()
! {
! var h = Math.max(self.innerHeight || 0, window.innerHeight || 0);
! if (document.documentElement)
! h = Math.max(h, document.documentElement.clientHeight || 0);
! if (document.body)
! {
! h = Math.max(h, document.body.clientHeight || 0);
! h = Math.max(h, document.body.scrollHeight || 0);
! h = Math.max(h, document.body.offsetHeight || 0);
! }
! return h;
! }
! };
! // shim layer with setTimeout fallback
! window.requestAnimFrame = (function(){
! return window.requestAnimationFrame ||
! window.webkitRequestAnimationFrame ||
! window.mozRequestAnimationFrame ||
! window.oRequestAnimationFrame ||
! window.msRequestAnimationFrame ||
! function (cb){
! window.setTimeout(cb, 1000 / 60);
! };
! })();
! //snowflakes.init(); ___hier eingefügt:
Dann ein HTML Widget zum Aufruf dieser Funktion verwendet:
HINWEIS: Der hier gezeigte Code stimmt nicht. habe falsche Bilder aus anderen Tests hochgeladen - sorry.Ich nutze den Code im html Fenster:
Bis hierhin alles bestens. Das Ganze sieht dann sehr schön animiert so aus:
Nun war der Gedanke, dass ein Widget mit einer Sichtbarkeitseinstellung auch dieses Javaskript steuern kann, so dass z. B. erst ab einer Temperatur unter 0°C dieses Skript läuft:
Nur das geht ja schon nicht, das Skript startet immer.
****ABER: Nicht nur diese einfache Sichtbarkeit war gewünscht, sondern eine zweifache Abfrage:
Wenn Sensor Temperatur unter 0°C ist UND der Regensensor True hat, erst dann soll das JS laufen.****
Und das klappt irgendwie noch gar nicht.
Mit Bluefoxs Antwort komme ich noch nicht klar, wo er da was und wie gemacht hat.___
-
CSS Allgemein / opacity:
{a:sensor1;b:sensor2;a <= "0" && b == "1" ? 1 :: 0} ```` `
Nur um sicher zu gehen; ich habe in den CSS Allgemein im Feld opacity folgendes eingegeben:
{a:hm-rpc.0.LEQ9999999.1.TEMPERATURE;b:hm-rpc.1.CUX0304142.1.STATE;a <= "0" && b == "1" ? 1 :: 0}
Wäre das so richtig?
Aber egal was ich versuche, das Script startet immer - besser gesagt, die Flocken sind immer da.
Ich stelle gerade fest, dass meine Browser machen, was sie wollen. Wenn ich 20x reload ohne Cache drücke, dann kommt mal Schnee, mal nicht.
Firefox will gar nichts mehr darstellen. Ich glaube, hier macht mir der Cache immer weider mal ein x für ein u vor.
Frage: Wie kann ich den Ausdruck oben mit den Sensoren "sehen" - also wo/in welcher Datei ist er drinnen als Wert? Ich habe nicht eine CSS gefunden (F12 im Chrome), wo die opacity überhaupt drinnen ist. Ich möchte es gerne wie üblich mit chrome oder FF analysieren.
-
Hallo Fitti,
bei dem Code von "Bluefox" braucht man kein Html Widget.
Einfach bei Skripte einfügen und es schneit. Vielen dank dafür Bluefox
Wie man deine Bedingungen einfügt weiß ich leider nicht.
Ich denke auch das es nicht über die Sichtbarkeit gehen wird.
Eher über eine if abfrage im Skript..
-
Dann h~~@Home4.0:~~
bei dem Code von "Bluefox" braucht man kein Html Widget.
Einfach bei Skripte einfügen und es schneit. Vielen dank dafür Bluefox `
Dann ist es ja identisch zu meinem Skript.Das verlinkte Script von Bluefox ist einfach zu mächtig.
Mein kopiertes ist da doch wesentlich schlanker und verbraucht weniger ressourcen.
Ich hatte auch schon das Skript angepasst
// init flake
…
el.style.opacity = '1.0';
Das geht auch - aber wie nur in Abhängigkeit mit meinen beiden Sensoren? :?
Selbst wenn ich die Zeile oben mit if Abhängigkeiten auf die Sensoren hinbekomme --> müsste das skript ja bei Bedarf sich dann Abschalten.
Hier ist die Crux, weshalb ich einen Teil auf ein Widget ausgelagert hatte.
Nun gut... man könnte auch ein animiertes Gif im Widget verwenden. Nur da klappt es ja auch nicht mit den beiden Sensoren, wie oben beschrieben.
-
Nun gut… man könnte auch ein animiertes Gif im Widget verwenden. Nur da klappt es ja auch nicht mit den beiden Sensoren, wie oben beschrieben. `
Schrieb's und machte das Ganze noch performanter und einfacher. Nur drei kleine Bilder und ein bissl CSS3.Und das Ganze sieht schon mal genial aus. Butterweich und nahezu keine Ressourcen 8-) .
Das geht sogar im Editor. :ugeek:
<u>Klick das Bild für eine Animation:</u>
578_leiserieseltderschnee.gif -
Auch nicht schlecht.
Kannst du denn die gif's in den Vordergrund legen und trotzdem alles bedienen?
-
Jain. Es sieht zwar so aus, aber durch den z-index kann man das steuern. Jedoch es geht alles, so wie ich es mir wünsche. Und ich habe wirklich eine Menge an Buttons drauf. Die opacity mit zwei Aktoren habe ich nun auch hinbekommen:
{mytemp:hm-rpc.0.LEQ999999.1.TEMPERATURE;rainsignal:hm-rpc.1.CUX0304142.1.STATE;mytemp <= "3.0" && rainsignal == "true" ? 1 : 0}
(klick Bild für Animation) Die kleinen Grafikfehler kommen vom Rendern der Animation.
578_snowing_ii.gif -
ich habe eine config seite da drin kann ich die design farbe usw einstellen.
Es wäre doch möglich eine Checkbox einzufügen für den Schnee.
Einer einen Tip wie ich das machen kann?
-
ich habe eine config seite da drin kann ich die design farbe usw einstellen.
Es wäre doch möglich eine Checkbox einzufügen für den Schnee.
Einer einen Tip wie ich das machen kann? `
Ich bin nicht ganz sicher, das Komma an der richtigen Stelle zu lesen…
(also was Du genau meinst, verstehe ich nicht).
Jedoch: Durch eine Checkbox kannst Du doch eine Variable setzen.
Und diese kannst Du dann wieder über die Opacity, so wie in der Beispielcodezeile gezeigt, abfragen.
Oder wenn es nur eine einzige Abfrage ist, dann über die "Sichtbarkeit" gehen.
-
checkbox schnee an oder schnee aus
-
<u><size size="150">Anleitung zum Nachbauen</size></u>
Für die, die es auch nachbauen wollen, hier der Link zum Ideengeber: https://fastwp.de/2677/
Das Ganze besteht einfach nur aus drei PNG Bilder mit Alphakanal (transparenter Hintergrund) (unter dem Link herunter ladbar).
Das Ganze besteht also nur aus drei PNG-Bilder, etwas CSS und einem Widget zur Steuerung der Größe der Bilder und der Sichtbarkeit.
Ich habe die Bilder mittels Dateimanager in vis rein geladen.
Im CSS Bereich habe ich dann folgendes eingegeben:
#w00207 { background-image:url('http://192.168.123.321:8082/vis.0/main/img/schnee1.png'),url('http://192.168.123.321:8082/vis.0/main/img/schnee2.png'),url('http://192.168.123.321:8082/vis.0/main/img/schnee3.png'); -webkit-animation:schnee 2s linear infinite; -moz-animation:schnee 2s linear infinite; -ms-animation:schnee 2s linear infinite; animation:schnee 2s linear infinite; } @keyframes schnee{0%{background-position:0px 0px,0px 0px,0px 0px}100%{background-position:500px 1000px,400px 400px,300px 300px}}@-moz-keyframes schnee{0%{background-position:0px 0px,0px 0px,0px 0px}100%{background-position:500px 1000px,400px 400px,300px 300px}}@-webkit-keyframes schnee{0%{background-position:0px 0px,0px 0px,0px 0px}100%{background-position:500px 1000px,400px 400px,300px 300px;}}@-ms-keyframes schnee{0%{background-position:0px 0px,0px 0px,0px 0px}100%{background-position:500px 1000px,400px 400px,300px 300px}}
#w00207 ist dabei das HTML Widget, welches ich dafür angelegt habe.
Hinweis: Bei mir zeigt der CSS Bereich Fehler an, die aber ignoriert werden können.
Ich weiß nicht, ob der Bilder-Aufruf nicht noch einfacher als mit der gesamten URL erfolgen kann, aber so mache ich es seit Jahren und es geht. Natürlich lasse ich iobroker nicht aus mein Haus raus, weshalb hier auch keine Probleme zu erwarten sind.
Das HTML-Widget ist wie gesagt nur zur Größenbestimmung und der Sichtbarkeits-Steuerung vorhanden.
Der Schnee soll nur angezeigt werden, wenn die Temperatur unter 3°C sinkt und der Regenmelder Regen/Schnee erkennt.
Hier noch einmal zur Vollständigkeit meine CSS Allgemein opacity:
{mytemp:hm-rpc.0.LEQ999999.1.TEMPERATURE;rainsignal:hm-rpc.1.CUX0304142.1.STATE;mytemp <= "3.0" && rainsignal == "true" ? 1 : 0}
Die Last ist erstaunlich gering.
Durch die z-index Variable kann man schön die Ebene bestimmen, wo der Schnee sein soll. Somit funktionieren auch noch Buttons oder andere Widgets.
Viel Spaß, falls es jemand nachbauen möchte.
So long,
-
ich habe versucht das Skript in der Vis zu verwenden, genau so wie es hier steht, nur kommt bei mir nichts.
-
@holly200289 hast du denn auch die Bilder hinterlegt und die URLs angepasst?
-
nein ich habe schon bei googel gesucht, aber noch nichts gefunden
-
Da muss ich eine vorlage hinterlegen richtig, von dieser wird alles abgeleitet ?
-
der thread ist zwar uralt, da aber dennoch wird nach einer lösung gefragt. hier für vis1
Schritt 1:
Skript von folgender Adresse kopieren
und im Skriptreiter von vis eintragen/ergänzen
https://www.go4u.de/files/javascript/snowflakes/snowflakes.jsSchritt2:
neues html widget platzierenSchritt3:
folgende skripte in das html feld des html widgets eintragen.skript ohne bedingungen
<script> snowflakes.start(); </script>
skript mit bedingungen
ich habe hier mal 2 datenpunkte gewählt, anhand deren dann bedingt das skript gestartet oder
das skript ist nun auf datenpunkte vom typ number eingestellt.
wer bspw string datenpunkte einfügen möchte, muss um den binding ausdruck noch anführungszeichen machen. der binding ausdruck ist sozusagen als platzhalter zu sehen, an deren stelle dann der reale wert nackt eingetragen wird. im ergebnis muss gültiges javascript herauskommen, sonst funktioniert es nicht. mit F12/Console kann nach fehler gescuht werden.
eine schleife ist ebenfalls nicht ntwendig, da das skript voll automatisch bei jeder dp änderung aufgerufen wird und die aktualisierten werte eingetragen werden.<script> let t1 = {0_userdata.0.t1}; let t2 = {0_userdata.0.t2}; if (t1>10 && t2>10) { snowflakes.start(); } else { snowflakes.stop(); } </script>
-
@oliverio Super vielen dank das funktioniert schonmal super
-
@oliverio Könnte ich das auch mit der Temperatur koppeln ?
-
@oliverio Danke für die Erklärung.
Eine Frage hätte ich nochDie Schneeflocken kommen bei mir nur auf dem Hintergrund. Ich habe den Z-Index des Html Widgets auf 50 gesetzt und immer noch den gleichen Effekt. Gibt es da einen Trick?
Edit:
In deinem Temperaturscript ist ein kleiner Fehler:<script> let t1 = {0_userdata.0.t1}; let t2 = {0_userdata.0.t2}; if (t1<10 && t2<10) { snowflakes.start(); } else { snowflakes.stop(); } </script>
Es soll ja vermutlich bei Temperaturern UNTER 10°C auslösen (Zeile 4)
-
@holly200289 Siehe das letzte script.
Den oder die Datenpunkte auswählen und anstelle von0_userdata.0.t1
bzw. t2 dann deinen Datenpunkt eintragen.
In Zeile 4 dann deine Auslösetemperatur eintragen (10° ist bischen warm für Schnee)Bei nur einem Datenpunkt sollte es dann theoretisch so funktionieren:
<script> let t1 = {sonoff.0.BLE_Sensoren.xxxxxxx_Temperature}; if (t1<4) { snowflakes.start(); } else { snowflakes.stop(); } </script>