Antwort an „Rolf B“ verfassen

Hallo Robert,

font-size

die Frage ist, was hier die Anforderung ist. Es gibt ja mehrere Rahmenbedingungen:

  • Anzeige soll GROẞ sein
  • Anzeige soll weder horizontal noch vertikal den Viewport überschreiten (egal ob das Viewportformat Portrait oder Landscape ist)

D.h. man muss die Größe der Box ermitteln, die für die Zeitanzeige nötig ist, und die Fontsize so wählen, dass sie weder zu hoch noch zu breit ist. Und dies bei jeder Größenänderung des Viewports und der Zoomstufe anpassen. Ich habe gerade keine Vorstellung, wie sich das mit CSS lösen ließe, das braucht meiner Meinung nach JavaScript. Wie bitte, Gunnar? Ob ich dein Bier halten kann? Klar…

dateFormatter.format vs Abfrage auf 10s

Wenn Du den dateFormatter verwendest, gibt's formattedMinutes etc nicht. Die sollte man eh nicht verwenden, sondern direkt mit den Millisekunden arbeiten. ICH würde eine const setzen, wo der Schwellwert drinsteht, ab dem das Audio spielen soll, und einfach abfragen, ob der Schwellwert überschritten ist. Die formatierten Sekunden sind dann irrelevant. Ähnliches gilt für die Abschaltung des Intervalltimers. Wenn man dann noch die Ermittlung der diversen Elemente aus der Timerfunktion heraushält, wird sie deutlich übersichtlicher:

function startCountdown() {
  const countdownDuration = 15*1000,
        audioDuration = 10*1000;

  const startTime = Date.now(),
        endTime = startTime + countdownDuration,
        playTime = endTime - audioDuration;

  const audioElement = document.getElementById("audio"),
        displayElement = document.getElementById("countdown"),
        dateFormatter = new Intl.DateTimeFormat(undefined, {
            'minute': 'numeric',
            'second': 'numeric',
            'fractionalSecondDigits': 1
          });

  const timer = setInterval(function() {
    const now = Date.now(),
    displayElement.textContent = dateFormatter.format(endTime - now);
   
    if (now >= playTime && audioElement.paused) audioElement.play();
    if (now >= endTime)  clearInterval(timer);
  }, 50);
}
window.addEventListener("load", startCountdown);

Ich habe statt new Date().getTime() noch die kürzere Variante Date.now() verwendet. Sie erzeugt kein unnötiges Date-Objekt.

Ob man nun window.onload=startCountdown verwendet oder die addEventListener-Version, ist vom Ablauf her wurscht. Die onload-Variante hat halt den Nachteil, dass sie ein Highlander ist (es kann nur Einen geben). Die addEventListener-Variante ist der Englishman (kann gesittet in der Schlange stehen).

Ich finde es auch „netter“, die play-Methode nur aufzurufen, wenn das Audio noch nicht spielt. Ist doch doof, wenn einem jemand zehnmal pro Sekunden "los mach schon" ins Ohr brüllt, wenn man schon längst macht. Wichtig ist es nicht, das audio-Element ist da entspannt und spielt einfach weiter, wenn man während des Abspielens play() aufruft.

Es ist auch wichtig, das Intervall nicht auf 100ms festzulegen. setInterval garantiert die Intervalldauer nicht, die Intervalle können länger sein. Deswegen lieber doppelt so oft die Anzeige aktualisieren, sonst kann das für die Leute, die in Spielhallen Hausverbot haben[1], zu visuellen Quirks führen.

Ich hatte ja noch überlegt, statt 10 die duration-Eigenschaft des Audio-Elements auszulesen, aber das bringt nix, weil dieser Ton über die 0 hinaus nachklingt.

Rolf

--
sumpsi - posui - obstruxi

  1. Weil ihr Auge so schnell ist, dass sie den Bewegungen der Räder folgen können und sie deshalb viel wahrscheinlicher gewinnen als die meisten von uns, für die das drehende Rad nur visueller Matsch ist ↩︎

freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar

Ihre Identität in einem Cookie zu speichern erlaubt es Ihnen, Ihre Beiträge zu editieren. Außerdem müssen Sie dann bei neuen Beiträgen nicht mehr die Felder Name, E-Mail und Homepage ausfüllen.

abbrechen