Le code HTML fourni représente une page Web affichant une horloge Morse. Cette horloge montre l’heure actuelle sous une forme lisible par l’homme et la convertit également en code Morse, permettant aux utilisateurs de jouer et d’arrêter l’audio du code Morse.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#currentTime, #morseOutput {
font-size: 1.5rem;
margin: 1rem 0;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #e0e0e0;
}
#morseOutput {
font-family: monospace;
white-space: pre-wrap;
word-wrap: break-word;
}
button {
font-size: 1rem;
padding: 0.5rem 1rem;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
margin: 0.5rem;
}
#playButton { background-color: #4CAF50; }
#playButton:hover { background-color: #45a049; }
#stopButton { background-color: #f44336; }
#stopButton:hover { background-color: #d32f2f; }
#visualIndicator {
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #ccc;
margin: 1rem auto;
}
</style>
</head>
<body>
<center>
<div id="currentTime"></div>
<div id="morseOutput"></div>
<div id="visualIndicator"></div>
<button id="playButton">Jouer en Morse</button>
<button id="stopButton">Arrêter</button>
</center>
<script>
const morseCode = {
'0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-',
'5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.',
':': '---...', ' ': ' '
};
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const visualIndicator = document.getElementById('visualIndicator');
const LED_ON = '#4CAF50';
const LED_OFF = '#ccc';
const dotDuration = 60; // ms
const dashDuration = dotDuration * 3;
const pauseBetweenSymbols = dotDuration;
const pauseBetweenLetters = dotDuration * 3;
const pauseBetweenWords = dotDuration * 7;
let isPlaying = false;
let frozenTime = null; // heure figée pendant la lecture
let oscillator = null;
let gainNode = null;
let rafId = null;
function getCurrentTime() {
const now = new Date();
return now.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
}
function translateToMorse(text) {
return text.split('').map(char => morseCode[char] || char).join(' ');
}
// Pendant la lecture on affiche l'heure FIGÉE : la vue correspond au son.
function updateTime() {
const timeToShow = isPlaying ? frozenTime : getCurrentTime();
document.getElementById('currentTime').textContent = timeToShow;
document.getElementById('morseOutput').textContent = translateToMorse(timeToShow);
}
// Construit UNE seule timeline partagée par le son ET la LED.
// events[] = intervalles [start, end] (en secondes) où le signal est ON.
function buildSchedule(morse) {
const events = [];
let t = 0;
for (const symbol of morse) {
if (symbol === '.' || symbol === '-') {
const dur = (symbol === '.' ? dotDuration : dashDuration) / 1000;
events.push({ start: t, end: t + dur });
t += dur + pauseBetweenSymbols / 1000;
} else if (symbol === ' ') {
t += (pauseBetweenWords - pauseBetweenSymbols) / 1000;
}
}
return { events, total: t };
}
function playMorseCode(morse) {
if (isPlaying) return;
isPlaying = true;
const { events, total } = buildSchedule(morse);
const startAt = audioContext.currentTime + 0.1; // petite avance de sécurité
oscillator = audioContext.createOscillator();
gainNode = audioContext.createGain();
oscillator.type = 'sine';
oscillator.frequency.setValueAtTime(600, startAt);
gainNode.gain.setValueAtTime(0, startAt);
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
// Son : gain planifié sur la même timeline que la LED.
events.forEach(ev => {
// petites rampes de 5 ms pour éviter les "clics"
gainNode.gain.setTargetAtTime(1, startAt + ev.start, 0.002);
gainNode.gain.setTargetAtTime(0, startAt + ev.end, 0.002);
});
oscillator.start(startAt);
oscillator.stop(startAt + total + 0.05);
oscillator.onended = () => finish();
// LED : pilotée par l'horloge AUDIO, pas par setTimeout -> aucune dérive.
function frame() {
const elapsed = audioContext.currentTime - startAt;
if (!isPlaying || elapsed >= total) {
visualIndicator.style.backgroundColor = LED_OFF;
return;
}
const on = events.some(ev => elapsed >= ev.start && elapsed < ev.end);
visualIndicator.style.backgroundColor = on ? LED_ON : LED_OFF;
rafId = requestAnimationFrame(frame);
}
rafId = requestAnimationFrame(frame);
}
function finish() {
isPlaying = false;
frozenTime = null;
if (rafId) { cancelAnimationFrame(rafId); rafId = null; }
visualIndicator.style.backgroundColor = LED_OFF;
if (oscillator) { try { oscillator.disconnect(); } catch (e) {} oscillator = null; }
if (gainNode) { try { gainNode.disconnect(); } catch (e) {} gainNode = null; }
updateTime(); // reprise immédiate de l'heure en direct
}
function stopMorseCode() {
if (!isPlaying) return;
if (oscillator) { try { oscillator.stop(); } catch (e) {} }
finish();
}
document.getElementById('playButton').addEventListener('click', () => {
if (isPlaying) return;
audioContext.resume(); // requis par la politique autoplay
frozenTime = getCurrentTime(); // on fige l'heure ICI
updateTime(); // et on l'affiche tout de suite
playMorseCode(translateToMorse(frozenTime));
});
document.getElementById('stopButton').addEventListener('click', stopMorseCode);
setInterval(updateTime, 1000);
updateTime();
</script>
</body>
</html>
Structure HTML
- Section Head:
- Élément Base : Spécifie l’URL de base pour les URL relatives sur la page comme
https://f4hxn.fr/. - Balises Meta : Définissent le jeu de caractères en UTF-8 et rendent la page responsive grâce à la balise meta viewport.
- Titre : Le titre de la page est « Horloge Morse – F4HXN. »
- Balise Style : Contient les styles CSS pour la mise en page et l’apparence.
- Section Body:
- Container : Un
<div>central avec la classecontainercontient tous les éléments interactifs. - Titre : Un élément
<h1>affiche le titre « Horloge Morse – F4HXN. » - Affichage de l’heure actuelle : Un
<div>avec l’IDcurrentTimeaffiche l’heure actuelle. - Sortie Morse : Un
<div>avec l’IDmorseOutputaffiche l’équivalent en code Morse de l’heure actuelle. - Indicateur visuel : Un
<div>avec l’IDvisualIndicatorsert d’indicateur visuel pour la lecture du code Morse. - Boutons : Deux boutons permettent à l’utilisateur de commencer (
playButton) et d’arrêter (stopButton) la lecture du code Morse.
Styles CSS
- Mise en page de la page :
- Le corps utilise Flexbox pour centrer le contenu verticalement et horizontalement.
- Un fond gris clair est appliqué au corps, tandis que le conteneur a un fond blanc avec une ombre pour le contraste.
- Typographie :
- La police est définie sur Arial, avec un texte centré dans le conteneur.
- Éléments interactifs :
- Les boutons changent de couleur au survol pour fournir un retour d’information à l’utilisateur.
- L’indicateur visuel est stylisé comme un élément circulaire qui change de couleur pour indiquer la lecture du code Morse.
Fonctionnalité JavaScript
- Mappage du code Morse : Un objet associe les chiffres et le caractère deux-points aux symboles du code Morse.
- Contexte audio : Utilise l’API Web Audio pour générer et contrôler la lecture audio des sons du code Morse.
- Durée du code Morse :
- Définit la durée des points, des traits et des pauses dans le code Morse.
- Fonctions principales :
getCurrentTime(): Récupère l’heure actuelle au formathh:mm:ss.updateTime(): Met à jour l’heure affichée et la traduit en code Morse.translateToMorse(text): Convertit un texte donné en code Morse en utilisant l’objet de mappage.playMorseCode(morseMessage): Joue le message en code Morse en manipulant les réglages de l’oscillateur et du gain pour produire du son.stopMorseCode(): Arrête la lecture du code Morse et réinitialise les paramètres audio.visualizeMorseCode(morseMessage): Fournit un retour visuel en animant l’indicateur visuel selon le timing du code Morse.- Écouteurs d’événements :
- Attache des événements de clic aux boutons de lecture et d’arrêt pour commencer et arrêter la lecture du code Morse.
- Un intervalle met à jour l’heure affichée chaque seconde pour s’assurer qu’elle reste à jour.
Cette page Web propose une horloge Morse interactive qui représente visuellement et audiblement l’heure actuelle en code Morse. Elle combine HTML pour la structure, CSS pour le style, et JavaScript pour la fonctionnalité, en utilisant l’API Web Audio pour la génération de son. Cette implémentation est efficace à des fins éducatives ou pour les passionnés intéressés par le code Morse et le développement Web.