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.