Ich habe eine Haussteuerung, bei der verschiedene Werte visualisiert werden. Es sind 10 verschiedene Seiten, momentan werden diese serverseitig generiert, Hierzu werden die Werte mit ImageMagik in ein bestehendes Foto eingefügt. ( Raspberry / simple Bash-Scripte, per Cronjob ausgelöst) Die fertigen Bilder werden alle 3 min von Tablets abgerufen und dort mittels einer Slideshow gezeigt - unten ein paar Beispielbilder. Will jetzt die ruhige Weihnachtszeit nutzen und das Ganze etwas moderner angehen. (In Bezug auf Umsetzung, Design soll so bleiben) Erste Überlegung ist - ich generiere auf dem Server pro Bild eine HTML-Datei mit Foto , Text und Werten, überschreibe die sich verändernden Werte wieder mit einem Bash-Script Es gibt dann eine übergeordnete Seite mit der Slideshow, hierfür gibts viele Beispiele im Netz (Alle die ich bisher gefunden habe können aber nicht direkt beliebigen Text an beliebigen Positionen einblenden) Nur, dann lädt jedes Tablett alle 5 sec jeweils die komplette Seite neu vom Server, obwohl sich nur ein paar Werte geändert haben? Wie hoch wird die Last am Raspberry dadurch? Wie würdet Ihr hier vorgehen? Bin aber zugegeben kein Programmierer, kennt jemand gute Beispiele? Ich brauche keine Touchfunktionalität. So was wie z.B. hier: https://blog.moneybag.de/wp-content/uploads/2015/11/tabletui-1-768x465.jpg will ich ausdrücklich nicht, will beim alten übersichtlichen Konzept bleiben Viele Grüße Heinz
Es gäbe ja da noch Ajax. Das reduziert die Last um einiges. Es setzt aber Programmierkenntnisse voraus. https://www.w3schools.com/js/js_ajax_examples.asp
:
Bearbeitet durch User
Ich würde es wie folgt machen: - Kleiner Webserver mit CGI am Rasp - CGI liefert bei Aufruf alle Daten als JSON - eine HTML Seite, unterteilt in 4 Felder: Strom, Solar, Heizung, Temp - pro Feld das jeweilige Hintergrundbild - Texte/Werte per HTML/CSS positionieren (zB table wo es lohnt) - JS/AJAX pullt alle n Minuten die Daten und aktualisiert Falls es Liveupdates sein sollen: Websockets.
SVG und AJAX oder Websocket würde ich verwenden. Die Werte als JSON übertragen und mit JS ins SVG einsetzen. Entweder die Werte per Websocket direkt senden, oder in eine JSON Datei schreiben und die Pollen. Ungetestet: (Den Abstand bei "xlink:href =" entfernen, kann der Admin das endlich mal beheben?) test.svg:
1 | <?xml version="1.0" encoding="UTF-8"?>
|
2 | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
3 | <svg xmlns="http://www.w3.org/2000/svg" |
4 | xmlns:xlink="http://www.w3.org/1999/xlink" |
5 | version="1.1" baseProfile="full" |
6 | viewBox="0 0 800 600"> |
7 | <desc>
|
8 | <style><![CDATA[ |
9 | text {
|
10 | font: 220px sans-serief;
|
11 | }
|
12 | ]]></style> |
13 | </desc>
|
14 | <title>SVG Beispiel</title> |
15 | <image xlink:href ="https://images.pexels.com/photos/730896/pexels-photo-730896.jpeg" x="0" y="0" width="800" height="600" /> |
16 | <text fill="#F00" x="450" y="180" data-value="bla">test</text> |
17 | <desc>
|
18 | <script><![CDATA[ |
19 | "use strict";
|
20 | function update(x){ // Text update function
|
21 | // Search vor all text elements
|
22 | for(var e of Array.from(document.getElementsByTagName("text"))){
|
23 | // Check if it has a data-value attribute
|
24 | if(!e.dataset || !('value' in e.dataset))
|
25 | continue; // If not, check next text element
|
26 | let prop = e.dataset.value; // get the value of the data-value attribute
|
27 | // Do our datas have a property with the same name as the data-value attributes' value?
|
28 | if(!prop || !(prop in x))
|
29 | continue; // If not, check next text element
|
30 | // Otherwise, get the value of that property and use it as text for the text element
|
31 | e.textContent = x[prop] || '';
|
32 | }
|
33 | }
|
34 | function poll(){ // Function which loads data, and then calls the update function
|
35 | fetch("./my-datas.json")
|
36 | .then(response=>update(response.json()));
|
37 | } |
38 | poll(); // Load data |
39 | setInterval(poll, 1000 * 5); // Load data again every 5 seconds |
40 | ]]></script>
|
41 | </desc>
|
42 | </svg>
|
my-datas.json:
1 | { |
2 | "bla": "1 ☃" |
3 | } |
Das tolle an SVG ist, dass es immer schön alles mit der viewbox skaliert, inklusive Text.
Ich würde dazu ein kleiner Web Server auf dem Raspberry Pi laufen lassen. In python zum Beispiel so:
1 | from bottle import route, request, run, static_file |
2 | |
3 | @route('/', name='static') |
4 | def serve_index(): |
5 | return static_file('index.html', root='./') #root gibt pfad an |
6 | |
7 | @route('/temperature', method='POST') |
8 | def get_temperature(): |
9 | return "5" |
10 | |
11 | run(host='0.0.0.0', port=80) |
Du kannst dann mit einer Website eine Anfrage an den Server schicken, und diese Daten empfangen (in diesem Bsp sollte das File index.html heissen, und an dem in root geschriebenen Pfad zu finden sein):
1 | <!DOCTYPE html>
|
2 | <html lang="en"> |
3 | <p>Temperatur: <span id=temperature></span></p> |
4 | <button onclick="request()">Make request</button> |
5 | <script>
|
6 | function request() { |
7 | var xhr = new XMLHttpRequest(); |
8 | xhr.responseType = 'text'; |
9 | xhr.onreadystatechange = function() { |
10 | if (xhr.readyState == XMLHttpRequest.DONE) { |
11 | document.getElementById( |
12 | "temperature").innerHTML=xhr.response; |
13 | }
|
14 | };
|
15 | xhr.open('POST', 'temperature'); //selber name wie in route(...) in python! |
16 | xhr.setRequestHeader('Content-Type', 'application/text'); |
17 | xhr.send("Give me temperature"); |
18 | }
|
19 | </script>
|
20 | </html>
|
Dies ist ein MWE, es kann dan entsprechend erweitert werden, und auch mehrere Daten auf einmal empfangen werden.
trampi schrieb: > python Getestet habe ich es unter python2.7, unter python3 weiss ich nicht ob es so lauffähig ist, anpassungen wären aber minimal.
DPA schrieb: > SVG und AJAX oder Websocket würde ich verwenden. Die Werte als JSON > übertragen und mit JS ins SVG einsetzen. Entweder die Werte per--- Danke DPA, das sieht schon mal sehr vielversprechend aus Bin nur wie gesagt kein Programmierer... Habe es geschafft das die Katze mit dem Text "test" dargestellt wird Der Wert 1 aus der my-datas.json leider nicht? Verstehe ich es richtig, das Hintergrundbild wird nur bei Scriptstart einmalig geladen, danach nur noch die Werte aktualisiert ? Das wäre perfekt. Viele Grüße Heinz
Heinz R. schrieb: > Habe es geschafft das die Katze mit dem Text "test" dargestellt wird > Der Wert 1 aus der my-datas.json leider nicht? Ich konnte den Teil noch nicht testen. War das Script auf einem Server, oder wurde wurde das Lokal von der Festplatte geöffnet? In letzterem fall verhindert die Same-Origin-Policy des Browsers den Zugriff. Und die Dateien müssen im gleichen Verzeichnis sein, damit es geht. > Verstehe ich es richtig, das Hintergrundbild wird nur bei Scriptstart > einmalig geladen, danach nur noch die Werte aktualisiert ? Das wäre > perfekt. Genau. Das ist beim Beispiel von @trampi ebenfalls der Fall, wenn man dort noch ein setInterval() hinzufügt, nur dass dort HTML statt SVG, XHR statt fetch, und ids stat data-attribute verwendet werden.
PS: Wenn sonst noch was fehlschlägt, müsste in der Browserkonsole eine Fehlermeldung zu finden sein.
Spiele gerade damit rum, habe es sowohl direkt vom Desktop getestet, jetzt auch vom Server - die Variable wird leider nicht geladen Fehlermeldung kommt aber auch keine, und man sieht in Chrome in der Entwicklungsumgebung das alle 5 sec die my-datas.json geladen wird. Ich suche mal weiter :-)
ich hatte das mal in Python implementiert um mit einer Logo zu kommunizieren. Der Python-Webserver liefert eine HTML-Datei und die passenden Images aus. Zusätzlich handelt das selbe Script die Abfragen und Befehle von und zur Logo und liefert den Status als XML. In der Html sah das so aus. <body onload="activate();"> function activate() { .init. showState(); } function showState() { xmlHttp=GetXmlHttpObject(); if(xmlHttp==null) { alert ("Browser does not support HTTP Request"); return; } xmlHttp.onload=stateChanged; xmlHttp.onerror=stateNotChanged; xmlHttp.open("GET","http://"+location.host+":1525",true); xmlHttp.send(null); } function stateChanged() { var xmlDoc=xmlHttp.responseXML; if(xmlDoc) { ....... setTimeout(showState,1000); } else { console.log("error"); document.getElementById("net").style["background-color"]="yellow"; ....... setTimeout(showState,5000); } } function stateNotChanged() { console.log("error"); document.getElementById("net").style["background-color"]="yellow"; setTimeout(showState,5000); }
:
Bearbeitet durch User
Bin leider nicht wirklich weiter gekommen. Versuche mich wie gesagt am Beispiel von DPA Mir ist nicht klar wie die Werte aus dem JSON überommen werden, vielleicht ist dort auch ein Fehler? Verstehe ich es richtig - die Werte liegen erst mal in Response.json? Was bedeutet for(var e of Array.from(document.getElementsByTagName("text"))){ ? Hier noch mal das Beispielscript: <script><![CDATA[ "use strict"; function update(x){ // Text update function // Search vor all text elements for(var e of Array.from(document.getElementsByTagName("text"))){ // Check if it has a data-value attribute if(!e.dataset || !('value' in e.dataset)) continue; // If not, check next text element let prop = e.dataset.value; // get the value of the data-value attribute // Do our datas have a property with the same name as the data-value attributes' value? if(!prop || !(prop in x)) continue; // If not, check next text element // Otherwise, get the value of that property and use it as text for the text element e.textContent = x[prop] || ''; } } function poll(){ // Function which loads data, and then calls the update function fetch("./my-datas.json") .then(response=>update(response.json())); } poll(); // Load data setInterval(poll, 1000 * 5); // Load data again every 5 seconds ]]></script>
> Mir ist nicht klar wie die Werte aus dem JSON überommen werden, > vielleicht ist dort auch ein Fehler? Sorry, ich bin gerade erst dazu gekommen, das auf meinen Server zu laden und auszuprobieren. (http://dpa.li/svg-fetch-example/test.svg) Ich hatte wirklich einen kleinen Fehler gemacht, die poll funktion sollte so aussehen:
1 | function poll(){ |
2 | fetch("./my-datas.json") |
3 | .then(response=>response.json()) |
4 | .then(data=>update(data)); |
5 | } |
Heinz R. schrieb: > Verstehe ich es richtig - die Werte liegen erst mal in response.json? Nunja, fetch() gibt ein Promise Objekt zurück, das ist ein "Versprechen", dass etwas passiert oder man etwas bekommt. Eine Promise kann erfolgreich sein, oder fehlschlagen. Mit der .then Funktion/Methode der Promise kann man auf den erfolgreichen Abschluss warten, bzw. eine (callback) Funktion aufrufen lassen, die das Objekt dann bekommt. Bei fetch() ist das ein Response Objekt. Dieses beinhaltet die Header, die der Server gesendet hat, und bietet Funktionen und Eigenschaften, mit denen man auf die eigentlichen Daten zugreifen/warten kann (.body, .blob(), .arrayBuffer()). Die .text() Funktion interpretiert die Daten gleich noch als Text, und die .json() Funktion, die ich verwendete, nimmt einem gleich noch das Parsen der JSON Daten im Text ab. Der Fehler von mir war, die Funktionen .json() und co. geben nicht direkt die Daten zurück, sondern ebenfalls ein Promise Objekt. Das muss so sein, weil die Daten ja noch nicht zwangsläufig alle gesendet/empfangen wurden, wenn die Methode aufgerufen wird. Auf die eigentlichen Daten muss ich also wider mit .then() warten, und das hatte ich vergessen zu tun. Ich kann hier beim zweiten .then() die Rückgabe des ersten nehmen, weil .then() die Rückgabe der Callbackfunktion immer als Promise zurück gibt. Die Ausdrücke wie x=>x+1 sind Arrow funktionen (aka. lambdas). x=>x+1 ist fast das gleiche wie function(x){return x+1;}.
:
Bearbeitet durch User
Hallo Daniel, vielen vielen Dank, es läuft jetzt :-) Habe auch etwas über SVG nachgelesen, eigentlich ist es für das was ich brauche wohl genau das Richtige, fast genau so habe ich mir meine Seiten mit Imagemagick bisher zusammen gebastellt, halt an die richtigen Stellen Werte und Text gesetzt. Es sollte ein Leichtes sein, so die meisten meiner Seiten neu anzulegen. Hast Du zufällig (oder gerne auch jemand anderes) eine gute Idee, wie ich das dann in eine Slideshow bekomme? Gehe ich Recht in der Annahme, wenn ich mir jetzt 10 solcher Seiten bastle, die dann mit einer der vielen im Web verfügbaren Slide-Show-Programme anlege, dann trotzdem jedes Mal die Hintergrundgrafik neu gelaaden wird? Vermutlich dauert es dann auch zu lange bis die JSON-Datei jedes Mal wieder neu eingelesen wurde? Viele Grüße Heinz
Heinz R. schrieb: > Will jetzt die ruhige Weihnachtszeit nutzen und das Ganze etwas moderner > angehen. (In Bezug auf Umsetzung, Design soll so bleiben) Du willst den Unterbau ändern, aber das Sichtbare gleich lassen? Gibts da einen konkrete Grund für? > Nur, dann lädt jedes Tablett alle 5 sec jeweils die komplette Seite neu > vom Server, obwohl sich nur ein paar Werte geändert haben? > Wie hoch wird die Last am Raspberry dadurch? Die komplette Seite heißt, so wie ich das sehe, weniger Text wie in deinem Beitrag. Simples HTML, wenn du es moderner willst noch etwas CSS. Wenn das einen Pi schon überlastet sollte es mich wundern.
Reinhard S. schrieb: > Du willst den Unterbau ändern, aber das Sichtbare gleich lassen? Gibts > da einen konkrete Grund für? Hallo Albert, Weil es ja irgendwie albern ist, jedes mal ein Bild zu generieren nur weil sich ein paar Bytes geändert haben Ich konnte / kann es nicht besser, das Ergebnis stimmt, aber irgendwie ist es wie von hinten durchs Knie in die Brust... Klar, Netzwerk, Raspberry usw geben das in Zeiten des Livestreams locker her, aber da mir eh langweilig war wollte ich was dazu lernen Kenne mich leider mit dem Ganzen zu wenig aus, Daniels Vorschlag war schon mal die richtige Richtung, bekomme ich so hin, jetzt hapert es halt noch an der Slideshow, bin leider eher der Kopierer als der Coder Mich wundert das nichts in der Richtung im Web zu finden ist, nutzt niemand so was?
Du wirst an Javascript nicht vorbei kommen. Mit Ajax ein paar DOM-Objekte aktualisieren ist nicht so wild. Und wieso nicht mit Javascript als Programmiersprache anfangen. Es muss auf der anderen Seite auch kein Riesiges Server-Konstrukt existieren. Das kann ein Pythonscript, welches den kompletten HTTP-Server zur Verfügung stellt, sein oder ein XML welches einfach generiert wird und auf dem Apache-Server rumliegt.
Ajax-Beispiele gibts viele Am Anfang z.B. dieses https://www.w3schools.com/xml/ajax_intro.asp Die Texte würde ich einfach als benannte DOM-Objekte machen. Das klappt mit <.... id="dingens".....> und document.getElementById("dingens") ganz gut.
:
Bearbeitet durch User
Heinz R. schrieb: > jetzt hapert es halt noch an der Slideshow Ich würde für jede Slide ein <div> anlegen in dem du den Inhalt jeweils frei gestalten kannst. Die divs liegen dann alle übereinander. Dann brauchst du noch ein Script, was die divs der Reihe nach anzeigt bzw. alle anderen ausblendet. Da müsste es aber auch fertige Bibliotheken geben, ich kenne aber gerade keine.
Heinz schrieb: > Gehe ich Recht in der Annahme, wenn ich mir jetzt 10 solcher Seiten > bastle, die dann mit einer der vielen im Web verfügbaren > Slide-Show-Programme anlege, dann trotzdem jedes Mal die > Hintergrundgrafik neu gelaaden wird? Nicht zwangsläufig. Wenn die SVG Grafik geladen wird, werden auch darin enthaltene Bilder geladen. Solange sich die Datei aber nicht ändert, kann diese auch gecached werden. Die meisten Server haben E-Tag Cacheing defaultmässig aktiviert. Das geht ungefähr so: * Der Browser fragt nach einer Datei. * Der Server liefert die Datei, zusammen mit einem eindeutigen wert (ETag), der nur diese Datei haben kann. * Der Browser cached Datei und merkt sich den ETag * Beim nächsten mal, wenn die Datei geladen wird, sendet der Server mit, dass er noch die Datei mit dem alten ETag hat. * Wenn die Datei auf dem Server sich nicht geändert hat, liefert der Server nur diese Info zurück, und nicht die ganze Datei. Der Browser verwendet dan die letzte Version aus dem Cache. Es gibt noch 3 weitere Cacheing varianten, bei denen der Request zum Server meist entfällt: * Zeitbasiert (Expires und/oder Cache-Control Headers, oft bei Bildern verwendet) * Application Cache: manuelles Aktualisieren in JS (Ermöglicht auch offline Verwendung nach erstem Seitenaufruf, komplex, selten verwendet) * Service Worker: Das Caching und Auflösen von Ressourcen wird in JS manuell gemacht (Ermöglicht auch offline Verwendung nach erstem Aufruf, komplex, selten verwendet) Und falls das Slideshow Programm alle Lädt, und dann nur noch ein und ausblendet, wird alles nur einmal geladen. Wobei bei vielen solchen SVGs, die alle paar Sekunden dann alle ihre Daten aktualisieren wollen, das nicht unbedingt ideal wäre. Heinz schrieb: > Hast Du zufällig (oder gerne auch jemand anderes) eine gute Idee, wie > ich das dann in eine Slideshow bekomme? Die SVGs enthalten JS, deshalb sollten sie, wenn diese in einer HTML Seite eingebunden werden, mit einem <embed/> oder <iframe></iframe> Tag geladen werden. Da gibt es viele Möglichkeiten. Wie soll die Slideshow denn reagieren? Soll das nächste Slide kommen, wenn man irgendwo klickt? Oder Automatisch? Braucht es noch irgendeinen Übergang, Miniaturansichten, oder Ähnliches? Hier mal eins mit Überblendung (wechselt zwischen allen Elementen mit .slide): https://jsfiddle.net/r12mfLk5/2/ Heinz R. schrieb: > Was bedeutet > for(var e of Array.from(document.getElementsByTagName("text"))){ ? document.getElementsByTagName("text") liefert alle <text> Elemente als NodeList. In den meisten Browsern ist eine NodeList aber nicht iterierbar (in der "for( of )" schleife verwendbar). Array.from macht aus der NodeList ein Array, dieses ist dann iterierbar (das geht, weil eine NodeList die anzahl Elemente als .length Eigenschaft hat. Beispiel: Array.from({0:'a',1:'b',2:'c',length:2}) ergibt ['a','b'] (früher musste man dafür noch Array.prototype.slice.call(objekt) verwenden)). for(var e of [...]) ist einfach eine Schleife, die für jedes Element von etwas iterierbarem einmal durchlaufen wird, wobei e jedes mal das nächste Element des Iterators beinhaltet. Also "for(let x of [1,2,3]){f(x);}" ruft f(x) 3 mal auf, mit x=1, dann x=2, dann x=3. var, let und const definieren Variablen mit leicht unterschiedlichen Geltungsbereich und Veränderbarkeit. var: in ganzer Funktion gültig. const und let: im momentanen block {} gültig. const: unveränderbar.
Hallo Daniel, vielen Dank, ich bin schwer beeindruckt, auch wenn ich zugegeben vieles auch nach 5 Mal lesen nicht verstehe :-) Du scheinst Dich sehr gut mit so was auszukennen? Dein Beispiel ist eigentlich genau wie es sein soll DPA schrieb: > Wie soll die Slideshow denn reagieren? Soll das nächste Slide kommen, > wenn man irgendwo klickt? Oder Automatisch? Braucht es noch irgendeinen > Übergang, Miniaturansichten, oder Ähnliches? Genau so wie in Deinem Beispiel, einfach nach paar Sekunden überblenden, Interaktion braucht es keine Die 10 Seiten sollen einfach durchlaufen, der von Dir gezeigte Überblend-Effekt reicht mehr als aus Verstehe die Fiddle-Seite zugegeben nicht ganz, HTML, JavaScript und CSS, wie kommt das dann am Ende alles zusammen? Das Bild mit der Katze ist weiterhin das ursprüngliche Skript, wo dann aus der JSON die Werte genommen werden? Ich könnte jetzt einfach 10 solcher Seiten anlegen, die alle aus einem gemeinsamen JSON die jeweiligen Daten holen? Oder besser getrente JSON-Dateien pro Bild? Verstehe noch nicht so ganz den Unterschied zwischen embed src und image src Will nicht zu viel Deiner Zeit beanspruchen, aber wenn Du magst, könntest Du mir evtl. so was wie in Deinem Beispiel zusammen stellen, wo dann einfach 3-5 Bilder hintereinander in einer Slideshow gezeigt werden? Denke das entsprechend anzupassen bekomme ich hin Viele Grüße Heinz
Heinz schrieb: > Du scheinst Dich sehr gut mit so was auszukennen? Ich bin Applikationsentwickler mit einem Systemtechniker Job, und wärend der letzten paar Jährchen hab ich, neben anderen Dingen, die meisten Internettechnologien und Web APIs gelernt oder zumindest mal angesehen. Ich mag dafür Frameworks & Libraries meist nicht so gerne. Heinz schrieb: > Verstehe die Fiddle-Seite zugegeben nicht ganz, HTML, JavaScript und > CSS, wie kommt das dann am Ende alles zusammen? Ich hab alles mal in ein tar.gz Archiv gepackt, ist im Anhang. Siehe die index.html Datei. (statt dem <link> tag hatte ich alles auch direkt in die Datei in ein <style> tag tun können, beim <script> täg genauso, wenn ich das src weggelassen hätte.). > Das Bild mit der Katze ist weiterhin das ursprüngliche Skript, wo dann > aus der JSON die Werte genommen werden? Ja > Ich könnte jetzt einfach 10 solcher Seiten anlegen, die alle aus einem > gemeinsamen JSON die jeweiligen Daten holen? Ja > Oder besser getrente JSON-Dateien pro Bild? Spielt keine grosse rolle. Bei einem JSON könnte man das Script noch anpassen, dass man die Datei nur einmal für alle Bilder holt, statt dass jedes Bild die neu abruft. Heinz schrieb: > Verstehe noch nicht so ganz den Unterschied zwischen embed src und image src Das embed bei <embed ist der HTML Tag, es gibt an was für ein HTML Element man will. img ist für Bilder, video für Videos, audio für Musik, iframe für andere Seiten, und embed für andere aktive Inhalte, wobei das Browser oft nicht so eng sehen. Bei normalen, statischen SVGs könnte man einfach ein img verwenden. Das SVG hier enthält aber JavaScript, Browser sollten dieses bei reinen Bildern nicht ausführen. Damit bleiben nur embed und iframe dafür übrig. Ein embed verhält sich eher wie ein img, die Grösse des Inhalts kann auf die Grösse des Elements Einfluss nehmen, etc. Bei iframes hätte man dafür noch Sandboxing optionen, scroll bars per default, und keine content-abhängigen Änderungen der iframe-box. Das src="..." in <embed src="url" /> ist ein Attribut des embed elements. Die darin enthaltene URL zeigt auf was auch immer darin angezeigt werden soll. Heinz schrieb: > Will nicht zu viel Deiner Zeit beanspruchen, aber wenn Du magst, > könntest Du mir evtl. so was wie in Deinem Beispiel zusammen stellen, wo > dann einfach 3-5 Bilder hintereinander in einer Slideshow gezeigt > werden? Für mehr Bilder kannst du einfach die <img/> oder <embed/> Zeile kopieren, und das src="" feld anpassen. Für das JS Script spielt es übrigens keine rolle, was für ein Element als Slide für die Slideshow verwendet wird, es schaut nur auf das class="slide" attribut, und das das Element mit diesem direkt in einem Element mit dem class="slideshow" attribut ist. Die Reihenfolge der Slides kann man ändern, indem man einfach die Elemente entsprechend umsortiert.
Ich bin schon fleissig am Seiten zusammenstellen, mit Deinem beigefügtem Beispiel sieht das schon mal sehr vielversprechend aus Kurze Frage, habe schon nach einigen Beispielen gesucht, leider bislang erfolglos Wie muss ich die Zeile <text fill="black" x="150" y="400" class="big" data-value="min">test</text> ändern, so das hinter dem min-Wert noch ein Text stehen kann? Wie müsste die Zeile aussehen um zu schreiben " Es hat "$min" Grad"? Oder brauche ich für " Es hat", "$min" und "Grad" jeweils einen neuen Befehl? Wenn ich noch das Grad-Zeichen haben will (°), muss ich das wohl als Ascii-Zeichen einfügen? Viele Grüße Klaus
Im moment ersetzt das Script einfach den Inhalt von Text-elementen mit dem data-value Attribut. Mit einer leichten anpassung kann man das auf beliebige Elemente anwenden: Die Zeile:
1 | // Search vor all text elements |
2 | for(var e of Array.from(document.getElementsByTagName("text"))){ |
Ersetzen durch:
1 | // For all elements with a data-value attribute |
2 | for(var e of Array.from(document.querySelectorAll("[data-value]"))){ |
Danach kann man z.B. ein tspan Element im text Element verwenden, um darin den Wert anzuzeigen:
1 | <text fill="#F00" x="0" y="180">The <tspan data-value="bla"></tspan></text> |
Hallo Daniel, vielen Dank, es funktioniert :-) hätte noch eine Frage: WIe stelle ich es am Besten an, das die Slides Bildschirmfüllend sind? Habe jetzt bei der jeweiligen SVG-Seite viewBox="0 0 800 450"> Die Hintergrundbilder lade ich mit <image x="0" y="0" width="800px" height="450px" xlink:href ="../media/thermometer_roh.jpg"> </image> positioniere dann entsprechend die Texte Je nach Display habe ich ja jetzt verschiedene Seitenverhältnisse, 16:9, 16:10, 4:3... Meine Bilder haben alle einen weissen Hintergrund - geht es irgendwie das jetzt graue auch entsprechend einzufärben? Oder mus ich die Viewbox so groß machen das es auf alle Fälle immer reicht? Also z.B. 1920 x 1200?
Heinz R. schrieb: > Meine Bilder haben alle einen weissen Hintergrund - geht es irgendwie > das jetzt graue auch entsprechend einzufärben? Im css file (css/style.css), in der css rule mit dem selector ".slide", ist die Hintergrundfarbe mit "background-color" angegeben. Weiss wäre #FFF Heinz R. schrieb: > WIe stelle ich es am Besten an, das die Slides Bildschirmfüllend sind? Im css file (css/style.css), in der css rule mit dem selector ".slide", ist das Skalierverhalten mit der "object-fit" Eigenschaft festgelegt. https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit Wobei "object-fit: fill;" aber bei SVGs in einem embed Element nicht funktioniert, und bei "object-fit: cover;" zwar immer der ganze Bildschirm ausgefüllt ist, aber eventuell der Text ausserhalb des Bildes liegen könnte. Oder mus ich die Viewbox so groß machen das es auf alle Fälle immer reicht? Eigentlich sollten nur die width und height Parameter eine rolle spielen. Diese sollen idealerweise das gleiche Seitenverhältnis wie die Viewbox haben. Man kann aber eigentlich das SVG so nicht bei verschiedenen Seitenverhältnissen garantiert den ganzen Bildschirm füllen lassen. Es gibt aber noch den Hack, width="100%" height="100%" zu setzen, und die viewBox wegzulassen. Dann füllt es den ganzen Bildschirm. Wenn man darin trotzdem noch eine Box mit bekanntem Seitenverältnis braucht, kann man ein svg Element mit width="100%" height="100%" und einer viewBox hin einpacken. Beispiel im Anhang. Das hatte ich früher mal bei meinem bubble-background verwendet: https://old.danielabrecht.ch/css/bubbles/images/bg.svg
Danke Daniel, der Hintergrund weiss sieht gut aus, reicht vollkommen :-) Meine ersten Versuche: http://kr-server.de:88/test Woher kommst Du? Würde Dir gerne mal ein Bier ausgeben :-) Freue mich das mein seit 3 Jahre vor mir her geschobenes Weihnachtsprojekt endlich mal was wird Falls Du noch nicht genervt bist: Versuche mich jetzt daran, eine Uhr einzubinden Habe hier ein Tutorial gefunden: https://www.bitsarefun.com/tutorials/create-animate-clock-css3/ wie schaffe ich es, diese zentriert einzubinden? Die geben den Hintergrund relativ mit 350 x 350 Pixel an, kann ich da irgendwie einen Offset vorgeben? Kann ich diese auch irgendwie dynamisch skalieren? Also das sie beim Fenster verkleinern auch kleiner wird?
:
Bearbeitet durch User
Dennis H. schrieb: > Du wirst an Javascript nicht vorbei kommen. Bin ich zu altmodisch, das ich sowas mit einem meta-refresh gelöst hätte? Klar, defintiv nicht das neuste. Aber genauso funktional, würde ich sagen.
Reinhard S. schrieb: > Dennis H. schrieb: >> Du wirst an Javascript nicht vorbei kommen. > > Bin ich zu altmodisch, das ich sowas mit einem meta-refresh gelöst > hätte? Klar, defintiv nicht das neuste. Aber genauso funktional, würde > ich sagen. Kommt immer auf den Traffic an den man auslösen möchte. Eine XML/Text-Datei vom Server holen und Javascript den Rest machen lassen im aktuellen Bild geht genauso gut wie ein MJPEG-Stream direkt abspielen oder einen XServer als Display nehmen. Und so wie ich das am Anfang gelesen habe wollte der Threaderöffner über die Refresh-Schöpfungshöhe hinaus. Mal ne Frage. Ich hatte mal vor kurzen SVG in Verbindung mit Javascript genutzt um Abläufe in einer Anlage als Animation darzustellen. Wie weit kann ich das Javascript in einem SVG denn in Richtung AJAX nutzen ?
Dennis H. schrieb: > Mal ne Frage. > Ich hatte mal vor kurzen SVG in Verbindung mit Javascript genutzt um > Abläufe in einer Anlage als Animation darzustellen. > Wie weit kann ich das Javascript in einem SVG denn in Richtung AJAX > nutzen ? Habs mir selbst beantwortet. Geht. In Verbindung mit Inkscape und Notepad++ für das Erstellen. window.requestAnimationFrame + XMLHttpRequest und Apache2 Funktioniert direkt in Firefox beim Aufruf vom SVG (mit externen *.JS)
:
Bearbeitet durch User
Heinz R. schrieb: > Woher kommst Du? Würde Dir gerne mal ein Bier ausgeben :-) Arlesheim, Basel Landschaft, Schweiz. Heinz R. schrieb: > wie schaffe ich es, diese zentriert einzubinden? Seit Flex boxen geht das noch relativ einfach, gibt aber viele Möglichkeiten: https://jsfiddle.net/g2xmho35/2/ Heinz R. schrieb: > Kann ich diese auch irgendwie dynamisch skalieren? Also das sie beim > Fenster verkleinern auch kleiner wird? Das geht momentan nur mit JavaScript, und ist etwas aufwendiger. Ich würde die Uhr halt auch einfach in SVG umsetzen. Hab mal schnell eine geschrieben, siehe Anhang.
Hallo Daniel, Basel ist gar nicht mal so weit, komme aus der Stuttgarter Gegend Du bist echt ein Genie, kurz mal so ne Uhr zu zaubern :-) Wie immer habe ich noch ein paar Fragen: - Die Uhr geht eine Stunde hinterher, wo kann ich das anpassen? Vermutlich muss ich nur irgendwo noch 30° für den Stundenzeiger hinzufügen? -Ich habe eine Seite für Wetter, anbei ein Screenshot Hier fehlt mir noch die richtige Idee, was ich statt dessen nehmen kann Alle Beispiele, die ich so im Netz finde, sind nicht wirklich gut aus der Ferne ablesbar Momentan kopiere ich in Deinem Script einfach mit <embed src="media/wetter.jpg" class="slide" /> jeweils das Bild ein Wie schaffe ich es, dass das Bild z.B. stündlich neu geladen wird? Das Wetterbild wird über ein php-script generiert, habe ich vor vielen Jahren mal im Netz gefunden und etwas angepasst, vielleicht lässt es sich ja auch einfach direkt als php einbinden? Viele Grüße Klaus
eine HTML bauen die dieses Bild enthält und mit Meta refresh alle Stunde refreshed
Das Script in der SVG von UTC auf Lokale Zeit geht mit let s = Date.now()/60000-(new Date()).getTimezoneOffset();
:
Bearbeitet durch User
Vielen Dank, jetzt passt es auch mit der Uhrzeit Mit der Wetterkarte komme ich auch voran, hänge gerade an folgendem: Mit <text fill="black" x="400" y="280" class="big" ><tspan data-value="wert1"></tspan></text> Kann ich die Variable "wert 1" aus der JSON als Text einfügen Mit <image x="10" y="20" width="280" height="280" xlink:href ="../media/wetter_icons/cloudy.svg" /> kann ich ein hinterlegtes Bild einfügen Wie schaffe ich es / wie ist die Syntax, um das "cloudy" in dieser Zeile mit einem Wert "wert2" aus der JSON zu ersetzen?
Eine Alternative die ich hin bekomme wäre evtl. die 4 Bilder für die Wetteranzeige bereits serverseitig bereit zu stellen Bisherige Idee war, dem Browser über die JSON zu sagen wie das Wetter wird, er dann das entsprechende Bild lädt in der JSON steht z.B. "Tag1" "sunny.svg", er lädt es dann Neue Idee wäre, es gibt nur noch Bild1.svg bis Bild4.svg , diese werden auf dem Server bereits erstellt / kopiert Nur, wie bekomme ich es hin das die Bilder regelmäßig neu geladen werden? Diese liegen ja im Browser-cache und werden erst mal nicht automatisch neu geladen?
> Eine alternative Methode ist die Verwendung einer Technik wie Ajax, > um eine Website (oder Teile) zu aktualisieren, ohne dass eine > vollständige Aktualisierung der Seite erforderlich ist, aber dies würde > auch erfordern, dass der Benutzer JavaScript in seinem Browser aktiviert. Siehe https://en.wikipedia.org/wiki/Meta_refresh und https://de.wikipedia.org/wiki/Ajax_(Programmierung)
:
Bearbeitet durch User
Die SVGs können natürlich auch Javascript enthalten :)
oh je, ich verstehe es immer weniger :-) Es gibt ja scheinbar zig Wege, Programmiersprachen, Möglichkeiten, Werte Und ich bin zugegeben kein Programmierer Habe mich auf das Beispiel von Daniel konzentriert, klappt soweit gut, alle Seiten sind fertig bis auf die eine mit dem Wetter Falls mir noch jemand helfen mag, habe mal die SVG und die JSON angehängt Es geht jetzt eigentlich nur noch darum - wie schaffe ich es, die in der JSON bei "icon1" bis "icon4" genannten Namen dynamisch entsprechend den folgenden Zeilen zu laden: <image x="10" y="50" width="220" height="220" xlink:href ="../media/wetter_icons/test123.svg" /> <image x="210" y="50" width="230" height="220" xlink:href ="../media/wetter_icons/cloudy-day-1.svg" /> <image x="410" y="50" width="230" height="220" xlink:href ="../media/wetter_icons/cloudy-day-1.svg" /> <image x="610" y="50" width="230" height="220" xlink:href ="../media/wetter_icons/snowy-5.svg" /> Viele Grüße Klaus
Das ist alles noch ungetestet. Classe oder sonstigen Identifier hinzufügen:
1 | <image x="10" y="50" width="220" height="220" xlink:href |
2 | ="../media/wetter_icons/test123.svg" class="weather" /> |
3 | <image x="210" y="50" width="230" height="220" xlink:href |
4 | ="../media/wetter_icons/cloudy-day-1.svg" class="weather" /> |
5 | <image x="410" y="50" width="230" height="220" xlink:href |
6 | ="../media/wetter_icons/cloudy-day-1.svg" class="weather" /> |
7 | <image x="610" y="50" width="230" height="220" xlink:href |
8 | ="../media/wetter_icons/snowy-5.svg" class="weather" /> |
Und dann am entprechenden Ort xlink:href setzen:
1 | // What are the URLs for the images? |
2 | var weatherNameImageMap = { |
3 | "rainsnow": "../media/wetter_icons/snowy-5.svg", |
4 | "cloudy": "../media/wetter_icons/cloudy-day-1.svg", |
5 | "404": "../media/wetter_icons/test123.svg" |
6 | }; |
7 | |
8 | function update(x){ |
9 | let weatherimages = Array.from(document.querySelectorAll("image.weather")); // Get all image elements with the weather class |
10 | // Set the xlink:href attribute of each image to the url for the image or to the "404" image if there is no url for that image specified in weatherNameImageMap |
11 | weatherimages[0].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon1] || weatherNameImageMap["404"]); |
12 | weatherimages[1].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon2] || weatherNameImageMap["404"]); |
13 | weatherimages[2].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon3] || weatherNameImageMap["404"]); |
14 | weatherimages[3].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon4] || weatherNameImageMap["404"]); |
15 | // Rest des Codes wie vorher lassen |
Hallo Daniel, versuche mich gerade daran, haut noch nicht ganz hin Ich glaube der 3. Abschnitt bei Dir - function update(x){ beisst sich irgendwie mit dem bisherigen Inhalt? Sobald ich das einfüge, werden die bisherigen Text-Werte nicht mehr angezeigt Viele Grüße und vielen Dank für Deine Unterstützung
Hallo Daniel, vielen vielen Dank, es scheint zu funktionieren, zumindest das was ich bislang testen konnte Leider ein anderes kleines Problem - generiere die Daten mit FHEM, und genau jetzt, als ich damit rum spielen wollte: Important EOL Notice: As of Thursday, Jan. 3, 2019, the YQL service at query.yahooapis.com will be retired. This will impact users of datatables.org as well as developers who creates features using this YQL service. To continue using our free Yahoo Weather APIs, use https://weather-ydn-yql.media.yahoo.com/forecastrss as your new API endpoint. Contact yahoo-weather-ydn-api@oath.com for credentials to onboard to this free Yahoo Weather API service. Other YQL based services that use query.yahooapis.com will no longer operate. Muss erst mal das wieder umstellen :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.