• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Für Zufalls-Uhr css anpassen

colaholiker

Mitglied
Hallo Leute,

bei Start meiner Webseite soll immer eine andere Uhr entstehen mit Hintergrundbild und >passenden< Zeigern (Quelle).

Ich erzeuge eine Random- Zahl und baue damit einen Pfad zu einer bestimmten Grafik (Ziffernblatt).
Damit wird das Bild als Hintergrund in einen Div- Bereich geladen.

Code:
    <link rel="stylesheet" href="a-Arbeitsfiles/css/uhr-16-style.css">
    <script>
        function bild_random() {
            var
                anzPix = 70;
                img = '<img id="bild2" style.backgroundImage="" src=\"' + 'a-Arbeitsfiles/images/Uhren/uhr-',
                b = Math.floor((Math.random() * anzPix) + 1),
                c = b.toString(),
                cl = c.length;
            if ( cl < 2 ) { c = '0' + c; }
            img += c;
            img += '.jpg';
            img += '\" alt=\"[Uhr]\"/>';
            return img;
        }
    </script>
</head>

...

    <div id= "div_sp4">
        <div class="clock">
            <script> document.write(bild_random()); </script>
            <div class="hour">
                <div class="hr" id="hr"></div>
            </div>
            <div class="min">
                <div class="mn" id="mn"></div>
            </div>
            <div class="sec">
                <div class="sc" id="sc"></div>
            </div>
        </div>
    </div>

...

    <script src="a-Arbeitsfiles/js/uhr-16.js"></script>
</body>
</html>

Im Div- Bereich werden dann die Zeiger über das Bild gelegt. Die js- Datei ist unten auf der Webseite verlinkt, das css-File steht oben im 'head' s.Code oben).

So sehen js und css aus:

Code:
[js]
const deg = 6;
const hr = document.querySelector('#hr');
const mn = document.querySelector('#mn');
const sc = document.querySelector('#sc');
setInterval(() => {
    let day = new Date();
    let hh = day.getHours() * 30;
    let mm = day.getMinutes() * deg;
    let ss = day.getSeconds() * deg;
    hr.style.transform = `rotateZ(${hh+(mm/12)}deg)`;
    mn.style.transform = `rotateZ(${mm}deg)`;
    sc.style.transform = `rotateZ(${ss}deg)`;
})

[css]
.clock
{
    width: 300px;
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
    /* background: url('../../a-Arbeitsfiles/images/uhren/uhr-16.jpg'); */
    background-size: cover;
}

.clock::before
{
    content: '';
    position: absolute;
    width: 15px;
    height: 15px;
    background: #fff; /* Zeigerachse */
    border-radius: 50%;
    z-index: 10000;
}
.clock .hour,
.clock .min,
.clock .sec
{
    position: absolute;
}
.clock .hour, .hr
{
    width: 160px;
    height: 160px;
}
.clock .min, .mn
{
    width: 190px;
    height: 190px;
}
.clock .sec, .sc
{
    width: 230px;
    height: 230px;
}
.hr, .mn, .sc
{
    display: flex;
    justify-content: center;
    /* align-items: center; */
    position: absolute;
    border-radius: 50%;
}
.hr:before
{
    content: '';
    position: absolute;
    width: 8px;
    height: 80px;
    background: black; /* #ff105e Zeiger Std */
    z-index: 10;
    border-radius: 6px 6px 0 0;
}
.mn:before
{
    content: '';
    position: absolute;
    width: 4px;
    height: 90px;
    background: black; /* Zeiger min */
    z-index: 11;
    border-radius: 6px 6px 0 0;
}
.sc:before
{
    content: '';
    position: absolute;
    width: 2px;
    height: 150px;
    background: #ff105e; /* #fff Zeiger sec */
    z-index: 12;
    border-radius: 6px 6px 0 0;
}

Meine Frage ist jetzt, wie ich es schaffe, für bestimmte Zifferblätter das css anzupassen. Dazu müßte ich sicher mit js die erzeugten Bildnamen verarbeiten.

Das stelle ich mir mit einer 'for of'- Schleife je css-version vor, etwa so:

for (let segment of ["bild-01", "bild-06", "bild-23"]) {css-typ1 aktiv}
for (let segment of ["bild-02", "bild-03", "bild-18"]) {css-typ2 aktiv}
...

Damit kann ich händisch mit den passenden Zifferblättern Gruppen für die css- Varianten bilden.

Wie muß dafür der 'div'-Bereich aussehen? Sollten da per js 'class'- Namen entsprechend geändert werden?

Die Uhr besitzt 3 Zeiger und einen Kreis für die Achse. Müßte ich deshalb 4 Klassen bedenken oder nur <div class="clock"> für alles?
Mit dem erstellen und löschen von Klassen komme ich noch nicht so klar.

Oder gibt es andere Methoden?

TIA
 
Werbung:
Guten Morgen @colaholiker
Ich denke, ich verstehe was Du vor hast: Anders als in dem verlinkten Beispiel ein Bild für den Hintergrund verwenden und darüber die Zeiger legen.
Müßte ich deshalb 4 Klassen bedenken oder nur <div class="clock"> für alles?
Es gibt sicher mehrere Möglichkeiten, das aufzuziehen. Ich empfehle, dem div.clock mit Javascript eine Klasse zuzuweisen und darüber dann im CSS die gesamte Gestaltung zu erledigen. Dazu die Klassen in einem Array ablegen und daraus durch eine Zufallsauswahl die Klasse zu holen, so wie Du es jetzt mit dem Bild machst. Und das Bild nicht in einem img-Tag sondern als Hintergrundbild, damit Du es mit CSS einstellen kannst.
Ich weiß nicht ob es dir schon bekannt ist, Klassen kannst Du am besten mit classList einstellen:

Und übrigens: document.write funktioniert in vielen Fällen, man kann aber auch bös damit scheitern. Am besten die Finger davon lassen. Und ein backgroundImage in einem img-Tag ist fehl am Platze.

Versuche ob Du mit diesem Hinweisen zum Ziel kommst und melde dich wieder, wenn nicht.
 
Hi Sempervivum,

Der Link zeigt die Quelle für die Uhrzeiger, die ich verwende. Wollte halt den Originalcode auch zeigen.
Ich denke, ich verstehe was Du vor hast: Anders als in dem verlinkten Beispiel ein Bild für den Hintergrund verwenden und darüber die Zeiger legen.
Das läuft bereits! Hab ja meinen Code gepostet. Nur eben kommen Schwarze Zeiger auf schwarzem Hintergrund nicht gut an :-(
Dazu die Klassen in einem Array ablegen und daraus durch eine Zufallsauswahl die Klasse zu holen,
Das ist nicht gut, weil das css auf das Bild abgestimmt werden soll (nix mit css-Zufall). Es wird weit weniger css-Varianten (5?) als Bilder (70...) geben. Da ich mir keine 'einfache' Automatik vorstellen kann, die den Bildern passende css-Varianten zuweist ( --> Kontrast, Stil etc.), stelle ich mir das etwa mit den 'for of' Zeilen wie in #1 vor. Eine Gruppe Bilder --> css-Variante x.
Ich empfehle, dem div.clock mit Javascript eine Klasse zuzuweisen und darüber dann im CSS die gesamte Gestaltung zu erledigen.
Ja, und die Random- Variable dient zu Benennung der Klasse. Das werde ich als nächstes versuchen.
Und das Bild nicht in einem img-Tag sondern als Hintergrundbild, damit Du es mit CSS einstellen kannst.
Na das war 'früher' mal ein 'normales' Bild. In einer (weiteren) css-Datei ist es auch formatiert. Und das klappt für das Hintergrundbild immer noch (dieselbe ID).
- In css müßte ich das Bild ja genauso random einstellen können (und die Zahl abgreifen), daher lasse ich das!
Und übrigens: document.write funktioniert in vielen Fällen, man kann aber auch bös damit scheitern. Am besten die Finger davon lassen. Und ein backgroundImage in einem img-Tag ist fehl am Platze.
Wie gesagt, läuft dieser Teil. Ich bin sogar zufrieden, keine Ladezeiten usw. zu sehen.

Ich werd nochmal zu Hintergrundbildern rechercieren wenn das <img>-Tag falsch ist.
Soll ja kein Problem sein, die Zeile im Random- Code anders aufzubauen.

Ok, meine nächsten Schritte sind jetzt, die Random- Zahl abzugreifen und das mit dem Klasse erzeugen...
C.
 
Werbung:
Es wird weit weniger css-Varianten (5?) als Bilder (70...) geben.
Dann verstehe ich jetzt, was Du mit for-of gemeint hast.
In dem Fall müsste man ein Array bzw. Objekt anlegen in diesem Stil:
Code:
const themes = [
  {img: 'bild1.jpg', cls: 'theme1'},
  {img: 'bild2.jpg', cls: 'theme1'},
  {img: 'bild3.jpg', cls: 'theme1'},
  // usw. für alle Bilder mit dem Theme1
  {img: 'bild7.jpg', cls: 'theme2'},
  {img: 'bild8.jpg', cls: 'theme2'},
  {img: 'bild9.jpg', cls: 'theme2'},
  // usw. mit weiteren Bildern und Klassen für Themes
];

// jetzt eine Zufallszahl ermitteln und in randomIdx speichern
const randomIdx = ...
// und auf das Array zugreifen:
const
    im = themes[randomIdx].img,
    cls = themes[randomIdx].cls,
    clkContainer = document.querySelector('div.clock');
clkContainer.classList.add(cls);
clkContainer.style.backgroundImage = `url(${im})`;
Dann ist schon mal das Hintergrundbild eingestellt und Du kannst im CSS die Farben der Zeiger zuweisen:
Code:
    /* Styles für Theme1: */
    .clock.theme1 #hr {
        /* Styles für Theme1 für den Stundenzeiger */
   }      
    .clock.theme1 #mn {
        /* Styles für Theme1 für den Minutenzeiger */
   }      
   .clock.theme1 #sc {
        /* Styles für Theme1 für den Sekundenzeiger */
   }

    /* Styles für Theme2: */
    .clock.theme2 #hr {
        /* Styles für Theme2 für den Stundenzeiger */
   }
Ungetestet aber so sollte es funktionieren. Vollkommen ohne document.write.
 
Vollkommen ohne document.write.
Daraufhin muß ich Deine Version mal testen.

Seit kurzem hab ich was Lauffähiges erreicht, ohne 'document.write' ging es aber nicht.

So bekomme ich eine globale Variable mit dem Bildnamen:
Code:
    <script>
        var rndBild = 'uhr-';
        function bild_random() {
            var
                anzPix = 70,
                img = '<img id="bild2" stylebackgroundImage="" src=\"' + 'a-Arbeitsfiles/images/Uhren/uhr-',
                b = Math.floor((Math.random() * anzPix) + 1),
                c = b.toString(),
                cl = c.length;
            if ( cl < 2 ) { c = '0' + c; }
            rndBild += c;
            img += c;
            img += '.jpg")';
            img += '\ alt=\"[Uhr]\"/>';
            return img;
        }
    </script>
Die 'rndBild' kann ich ins Funktions- File bekommen , ganz unten im HTML:
Code:
clockClass(rndBild);
Da geht's weiter, und auch ich verwende Arrays, statt der 'for of'- Sache:
Code:
function clockClass(rndBild) {
    const
        listCl = document.getElementById("zeiger").classList,
        listhr = document.getElementById("hr").classList,
        listmn = document.getElementById("mn").classList,
        listsc = document.getElementById("sc").classList;
        
        let isthrue1 = ["uhr-01", "uhr-02", "uhr-03", "uhr-04", "uhr-05", "uhr-06",
                         "uhr-07", "uhr-08", "uhr-09", "uhr-10", "uhr-11", "uhr-12",
                         "uhr-13", "uhr-14", "uhr-15", "uhr-16", "uhr-17", "uhr-18"];

        if (isthrue1.includes(rndBild)) {
            /*
            listCl.remove('clock2');
            listhr.remove('hr2');
            listmn.remove('mn2');
            listsc.remove('sc2');
            */
            listCl.add('clock');
            listhr.add('hr');
            listmn.add('mn');
            listsc.add('sc');
        }

        let isthrue2 = ["uhr-21", "uhr-22", "uhr-23", "uhr-24", "uhr-25", "uhr-26",
                             "uhr-27", "uhr-28", "uhr-29", "uhr-30", "uhr-31", "uhr-32",
                             "uhr-33", "uhr-34", "uhr-35", "uhr-36", "uhr-37", "uhr-38"];


        if (isthrue2.includes(rndBild)) {
            /*
            listCl.remove('clock');
            listhr.remove('hr');
            listmn.remove('mn');
            listsc.remove('sc');
            */
            listCl.add('clock2');
            listhr.add('hr2');
            listmn.add('mn2');
            listsc.add('sc2');
        }
}
Paar Fragen:
- ist es besser, die Klassen zu removen (hier: deaktiviert, funktioniert auch so),
- Ich wollte eigentlich immer denselben Arraynamen verwenden. Das geht nicht. Muß ich das Array vorher löschen?
- Die Klassen im HTML habe ich entfernt. Kann man die drinlassen, so als Rückfallebene?

Wie Du siehst, muß ich 4 Klassen ändern. Hält sich aber trotzdem in Grenzen.

Die 2 Klassenvarianten lassen sich einfach erweitern und sind für mich später gut nachvollziehbar.

Ich habe zwecks Test noch keine Zuordnung bestimmter Grafiken zu den Klassen vorgenommen.
Das, die Erweiterung auf weitere Klassen und das Feilen an den css-Werten folgen noch.

Und wenn's langweilig wird, kann ich ja Zeiger mit Schnörkeln bauen ;-)
 
- ist es besser, die Klassen zu removen (hier: deaktiviert, funktioniert auch so),
Du schriebst ja, dass Du die Uhr nur einmalig beim Laden der Seite stylen willst, dann brauchst Du es nicht zu tun.
- Ich wollte eigentlich immer denselben Arraynamen verwenden. Das geht nicht. Muß ich das Array vorher löschen?
Um das zu beantworten, müsste man wissen, was Du genau probiert hast. Da Du die Arrays mit let definiert hast, müssten sie sich problemlos überschreiben lassen.
Und wenn Du meinen Vorschlag annehmen würdest, würde sich die Frage gar nicht stellen: Alles in einem Array und direkter Zugriff mit einer Zufallszahl, if-Abfragen braucht es nicht.
 
Werbung:
Guten Morgen Sempervivum,
ja, Dein Code gefällt mir jetzt auch besser, vor allem wenn die Array- Inhalte untereinander stehen.

Ich hab meine Files entsprechend umgestellt. Und das Beste: heute klappt es, ein Hintergrundbild zu erzeugen! Weiß nicht was gestern falsch lief, als ich es mit dem <p>- Tag probiert hatte. 'document.write' ist Geschichte!

Jetzt hackt's nur noch beim css. Dein Beispiel ändert ja nur .clock. Muß ich nicht auch die Zeiger- Klassen (ähnlich wie in meinem Code) auf das Theme erweitern?
Die IDs anzusprechen bringt doch nichts, weil die immer gleich sind?

Da bin ich gerade dran...
 
Sieh dir genau mein CSS in #4 an:
Code:
    /* Styles für Theme1: */
    .clock.theme1 #hr {
        /* Styles für Theme1 für den Stundenzeiger */
   }
Es spricht nicht einfach das Element mir der ID "hr" an sondern die Anweisungen werden nur wirksam wenn das Vorfahrenelement mit der Klasse "clock" auch die Klasse "theme1" hat. Oder anders herum formuliert: Hat der Container mit der Klasse "clock" auch die Klasse "theme1" dann und nur dann führe für das Nachfahrenelement mit der ID "hr" die CSS-Anweisungen aus. Hat das Element ".clock" z. B. die Klasse "theme2" wird dieses CSS nicht wirksam.

Das erspart uns, für jeden einzelnen Zeiger die entspr. Klasse zu setzen

Siehe auch hier:
 
Alles klar, dann baue ich das mal so auf.
Es gibt aber weitere "bunte" Formatprobleme für das Hintergrundbild, was ich auf das Fehlen der css- Anweisungen für das "alte Bild aus der Vorgeschichte" mit der ID 'bild2' (s. Code #1) zurückführe.

Da muß ich evtl. noch was davon übernehmen. Wäre auch gut, dem Hintergrundbild diese ID zu geben.
Richtet sich diese Art Hintergrundbild (statt der 'document.write' Variante) css-mäßig auch nach der ID und wie sieht die ID- Implementierung in der Zeile
Code:
clkContainer.style.backgroundImage = `url(${path + im})`;
aus? (nicht wundern wg. path!)
 
Werbung:
Der clkContainer wird in meinem Beispiel so bereit gestellt:
Code:
clkContainer = document.querySelector('div.clock');
d. h. er wird nicht über eine ID sondern die Klasse "clock" angesprochen.
 
So jetzt hab ich's. Durch die korrekten Bezeichnungen im css-Bereich ist die Formatierung gelungen. Die ID 'bild02' wird nicht benötigt.

Warum nur der Stundenzeiger theme1 in der Ecke links oben gelandet ist hab ich nicht rausbekommen, daher einfach theme 2 hochkopiert und in theme1 umbenannt, Farben angepaßt. Damit war das erschlagen.

Am Ende war nur noch zu beachten, daß das Array ja bei 0 beginnt, randomIdx 69 ist also uhr-70.
Doof! Aber läuft jetzt alles.

Vielen Dank Sempervivum mal wieder für Deine kompetente Hilfe!
 
Werbung:
Zurück
Oben