Traducteur de code Morse
Saisissez votre texte : la traduction s’affiche en direct, et vous pouvez l’écouter à la vitesse de votre choix.
Vitesse
20 WPM
Tonalité
600 Hz
Chronologie standard PARIS : point = 1 temps, trait = 3 temps, espace entre signes = 1 temps, entre lettres = 3 temps, entre mots = 7 temps. À 20 WPM, un temps dure 60 ms.
Le code source
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="F4HXN">
<meta name="description" content="Traducteur de code Morse avec lecture audio a vitesse reglable (WPM), ponctuation et chiffres - F4HXN">
<meta name="copyright" content="CC0 1.0 Universel">
<title>Traducteur de Code Morse — F4HXN</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root{
--bleu:#0076a5;
--bleu-clair:#298ad4;
--encre:#0f1e28;
--gris:#5a6b75;
--trait:#e2e8ec;
--fond-doux:#f5f8fa;
--blanc:#ffffff;
}
*{box-sizing:border-box}
.fmorse{
font-family:"DM Sans",system-ui,sans-serif;
color:var(--encre);
max-width:1200px;
margin:0 auto;
line-height:1.6;
}
.fmorse .fm-wrap{
background:var(--blanc);
border:1px solid var(--trait);
border-radius:14px;
padding:28px;
}
.fmorse h2.fm-titre{
font-size:1.5rem;
font-weight:700;
margin:0 0 4px;
color:var(--encre);
letter-spacing:-.01em;
}
.fmorse .fm-sous{
margin:0 0 22px;
color:var(--gris);
font-size:.95rem;
}
.fmorse label{
display:block;
font-size:.82rem;
font-weight:600;
text-transform:uppercase;
letter-spacing:.05em;
color:var(--bleu);
margin:0 0 8px;
}
.fmorse textarea{
width:100%;
min-height:96px;
resize:vertical;
font-family:"DM Sans",sans-serif;
font-size:1.05rem;
line-height:1.5;
color:var(--encre);
background:var(--blanc);
border:1px solid var(--trait);
border-radius:10px;
padding:14px 16px;
transition:border-color .15s ease, box-shadow .15s ease;
}
.fmorse textarea:focus{
outline:none;
border-color:var(--bleu-clair);
box-shadow:0 0 0 3px rgba(41,138,212,.15);
}
.fmorse .fm-sortie-bloc{margin-top:22px}
.fmorse .fm-sortie{
font-family:"JetBrains Mono",ui-monospace,monospace;
font-size:1.2rem;
line-height:2;
letter-spacing:.02em;
color:var(--bleu);
background:var(--fond-doux);
border:1px solid var(--trait);
border-radius:10px;
padding:16px 18px;
min-height:64px;
word-break:break-word;
white-space:pre-wrap;
}
.fmorse .fm-sortie:empty::before{
content:"Le code Morse s’affichera ici.";
color:var(--gris);
font-family:"DM Sans",sans-serif;
font-size:.95rem;
letter-spacing:normal;
}
.fmorse .fm-car{
display:inline-block;
padding:0 2px;
border-radius:4px;
transition:background .08s linear, color .08s linear;
}
.fmorse .fm-car.actif{
background:var(--bleu-clair);
color:var(--blanc);
}
.fmorse .fm-controles{
display:grid;
grid-template-columns:1fr 1fr;
gap:20px;
margin-top:22px;
padding:20px;
background:var(--fond-doux);
border:1px solid var(--trait);
border-radius:10px;
}
.fmorse .fm-reglage .fm-reglage-tete{
display:flex;
justify-content:space-between;
align-items:baseline;
margin-bottom:8px;
}
.fmorse .fm-reglage-tete span:first-child{
font-size:.82rem;
font-weight:600;
text-transform:uppercase;
letter-spacing:.05em;
color:var(--bleu);
}
.fmorse .fm-valeur{
font-family:"JetBrains Mono",monospace;
font-weight:700;
font-size:.95rem;
color:var(--encre);
}
.fmorse input[type=range]{
width:100%;
height:6px;
-webkit-appearance:none;
appearance:none;
background:var(--trait);
border-radius:3px;
outline:none;
}
.fmorse input[type=range]::-webkit-slider-thumb{
-webkit-appearance:none;
appearance:none;
width:20px;height:20px;border-radius:50%;
background:var(--bleu);
cursor:pointer;
border:3px solid var(--blanc);
box-shadow:0 0 0 1px var(--trait);
}
.fmorse input[type=range]::-moz-range-thumb{
width:20px;height:20px;border-radius:50%;
background:var(--bleu);
cursor:pointer;
border:3px solid var(--blanc);
}
.fmorse input[type=range]:focus-visible::-webkit-slider-thumb{
box-shadow:0 0 0 3px rgba(41,138,212,.35);
}
.fmorse .fm-boutons{
display:flex;
flex-wrap:wrap;
gap:12px;
margin-top:22px;
}
.fmorse button{
font-family:"DM Sans",sans-serif;
font-size:1rem;
font-weight:600;
padding:12px 22px;
border-radius:10px;
cursor:pointer;
border:1px solid transparent;
transition:background .15s ease, opacity .15s ease;
}
.fmorse .fm-jouer{background:var(--bleu);color:var(--blanc)}
.fmorse .fm-jouer:hover{background:var(--bleu-clair)}
.fmorse .fm-stop{background:var(--blanc);color:var(--bleu);border-color:var(--trait)}
.fmorse .fm-stop:hover{background:var(--fond-doux)}
.fmorse .fm-copier{background:var(--blanc);color:var(--gris);border-color:var(--trait)}
.fmorse .fm-copier:hover{background:var(--fond-doux)}
.fmorse button:disabled{opacity:.45;cursor:not-allowed}
.fmorse button:focus-visible{outline:2px solid var(--bleu-clair);outline-offset:2px}
.fmorse .fm-note{
margin-top:16px;
font-size:.85rem;
color:var(--gris);
}
@media (max-width:640px){
.fmorse .fm-wrap{padding:20px}
.fmorse .fm-controles{grid-template-columns:1fr}
.fmorse .fm-boutons button{flex:1 1 auto}
}
@media (prefers-reduced-motion:reduce){
.fmorse *{transition:none!important}
}
</style>
</head>
<body>
<div class="fmorse">
<div class="fm-wrap">
<h2 class="fm-titre">Traducteur de code Morse</h2>
<p class="fm-sous">Saisissez votre texte : la traduction s’affiche en direct, et vous pouvez l’écouter à la vitesse de votre choix.</p>
<label for="fm-texte">Texte à traduire</label>
<textarea id="fm-texte" placeholder="Entrez votre texte ici — lettres, chiffres et ponctuation sont pris en charge."></textarea>
<div class="fm-sortie-bloc">
<label for="fm-sortie">Code Morse</label>
<div id="fm-sortie" class="fm-sortie" aria-live="polite"></div>
</div>
<div class="fm-controles">
<div class="fm-reglage">
<div class="fm-reglage-tete">
<span>Vitesse</span>
<span class="fm-valeur"><span id="fm-wpm-val">20</span> WPM</span>
</div>
<input type="range" id="fm-wpm" min="5" max="35" step="1" value="20" aria-label="Vitesse en mots par minute">
</div>
<div class="fm-reglage">
<div class="fm-reglage-tete">
<span>Tonalité</span>
<span class="fm-valeur"><span id="fm-freq-val">600</span> Hz</span>
</div>
<input type="range" id="fm-freq" min="400" max="900" step="10" value="600" aria-label="Fréquence de la tonalité en hertz">
</div>
</div>
<div class="fm-boutons">
<button type="button" class="fm-jouer" id="fm-jouer">Écouter</button>
<button type="button" class="fm-stop" id="fm-stop" disabled>Arrêter</button>
<button type="button" class="fm-copier" id="fm-copier">Copier le Morse</button>
</div>
<p class="fm-note">Chronologie standard PARIS : point = 1 temps, trait = 3 temps, espace entre signes = 1 temps, entre lettres = 3 temps, entre mots = 7 temps. À 20 WPM, un temps dure 60 ms.</p>
</div>
</div>
<script>
(function(){
var MORSE = {
'A':'.-','B':'-...','C':'-.-.','D':'-..','E':'.','F':'..-.','G':'--.',
'H':'....','I':'..','J':'.---','K':'-.-','L':'.-..','M':'--','N':'-.',
'O':'---','P':'.--.','Q':'--.-','R':'.-.','S':'...','T':'-','U':'..-',
'V':'...-','W':'.--','X':'-..-','Y':'-.--','Z':'--..',
'0':'-----','1':'.----','2':'..---','3':'...--','4':'....-','5':'.....',
'6':'-....','7':'--...','8':'---..','9':'----.',
'.':'.-.-.-',',':'--..--','?':'..--..',"'":'.----.','!':'-.-.--',
'/':'-..-.','(':'-.--.',')':'-.--.-','&':'.-...',':':'---...',
';':'-.-.-.','=':'-...-','+':'.-.-.','-':'-....-','_':'..--.-',
'"':'.-..-.','$':'...-..-','@':'.--.-.',
'É':'..-..','È':'.-..-','À':'.--.-','Ç':'-.-..','Ù':'..--'
};
var texte = document.getElementById('fm-texte');
var sortie = document.getElementById('fm-sortie');
var wpm = document.getElementById('fm-wpm');
var freq = document.getElementById('fm-freq');
var wpmVal = document.getElementById('fm-wpm-val');
var freqVal= document.getElementById('fm-freq-val');
var bJouer = document.getElementById('fm-jouer');
var bStop = document.getElementById('fm-stop');
var bCopier= document.getElementById('fm-copier');
var audioCtx = null;
var timers = [];
var enLecture = false;
var lettres = []; // modele : { code, span, motAvant }
// --- Traduction en direct + construction du modele ---
function traduire(){
var t = texte.value;
sortie.innerHTML = '';
lettres = [];
var motAvant = false; // un espace precede-t-il la prochaine lettre ?
var premiere = true;
for (var i=0;i<t.length;i++){
var brut = t[i];
if (/\s/.test(brut)){
if (!premiere) motAvant = true;
sortie.appendChild(document.createTextNode(' '));
continue;
}
var code = MORSE[brut.toUpperCase()];
if (!code) continue; // caractere non pris en charge : ignore
var span = document.createElement('span');
span.className = 'fm-car';
span.textContent = code;
sortie.appendChild(span);
sortie.appendChild(document.createTextNode(' '));
lettres.push({ code: code, span: span, motAvant: motAvant });
motAvant = false;
premiere = false;
}
}
function texteMorse(){
return texte.value.toUpperCase().split('').map(function(c){
if (/\s/.test(c)) return '/';
return MORSE[c] || '';
}).filter(function(x){return x!=='';}).join(' ');
}
// --- Lecture audio, timing PARIS ---
function stop(){
enLecture = false;
timers.forEach(clearTimeout);
timers = [];
if (audioCtx){ try{ audioCtx.close(); }catch(e){} audioCtx = null; }
var actifs = sortie.querySelectorAll('.fm-car.actif');
for (var i=0;i<actifs.length;i++) actifs[i].classList.remove('actif');
bStop.disabled = true;
bJouer.disabled = false;
}
function jouer(){
stop();
if (!lettres.length) return;
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var u = 1.2 / parseInt(wpm.value,10); // duree d'un temps, en secondes
var f = parseInt(freq.value,10);
var t0 = audioCtx.currentTime + 0.15;
var curseur = t0;
var osc = audioCtx.createOscillator();
var gain = audioCtx.createGain();
osc.type = 'sine';
osc.frequency.value = f;
gain.gain.value = 0;
osc.connect(gain).connect(audioCtx.destination);
osc.start(t0);
function bip(debut, duree){
var r = 0.006; // rampe anti-clic
gain.gain.setValueAtTime(0, debut);
gain.gain.linearRampToValueAtTime(0.28, debut + r);
gain.gain.setValueAtTime(0.28, debut + duree - r);
gain.gain.linearRampToValueAtTime(0, debut + duree);
}
enLecture = true;
bJouer.disabled = true;
bStop.disabled = false;
for (var i=0;i<lettres.length;i++){
var L = lettres[i];
// espace AVANT la lettre : 3 temps entre lettres, 7 temps entre mots
if (i > 0) curseur += (L.motAvant ? 7*u : 3*u);
// surlignage synchronise
(function(span, debut){
timers.push(setTimeout(function(){
if(!enLecture) return;
var a = sortie.querySelectorAll('.fm-car.actif');
for (var k=0;k<a.length;k++) a[k].classList.remove('actif');
span.classList.add('actif');
}, (debut - t0) * 1000));
})(L.span, curseur);
// signes de la lettre, avec 1 temps entre chaque signe
for (var j=0;j<L.code.length;j++){
var d = L.code[j]==='-' ? 3*u : u;
bip(curseur, d);
curseur += d;
if (j < L.code.length - 1) curseur += u;
}
}
var finMs = (curseur - t0) * 1000 + 250;
timers.push(setTimeout(function(){ if(enLecture) stop(); }, finMs));
}
// --- Evenements ---
texte.addEventListener('input', function(){ if(enLecture) stop(); traduire(); });
wpm.addEventListener('input', function(){ wpmVal.textContent = wpm.value; });
freq.addEventListener('input', function(){ freqVal.textContent = freq.value; });
bJouer.addEventListener('click', jouer);
bStop.addEventListener('click', stop);
bCopier.addEventListener('click', function(){
var m = texteMorse();
if(!m) return;
navigator.clipboard.writeText(m).then(function(){
var ancien = bCopier.textContent;
bCopier.textContent = 'Copié';
setTimeout(function(){ bCopier.textContent = ancien; }, 1200);
});
});
traduire();
})();
</script>
</body>
</html>
Fiche technique
- Domaine
- CW Morse
- Difficulté
- ★☆☆☆☆ — Facile
- Temps estimé
- Environ 1 minute de lecture
- Nombre de vues
- 2 855 vues
- Créé le
- 22 décembre 2023
- Mis à jour le
- 2 août 2026

L’intelligence artificielle a participé au processus de rédaction de cet article en apportant une assistance à la mise en page, à la correction de la syntaxe, de la grammaire, de l’orthographe et d’éventuelles erreurs ou améliorations de formulation.
Certains schémas, codes, illustrations ou éléments graphiques peuvent également avoir été réalisés avec l’aide d’outils d’intelligence artificielle.
En savoir plus ...
Certains schémas, codes, illustrations ou éléments graphiques peuvent également avoir été réalisés avec l’aide d’outils d’intelligence artificielle.
En savoir plus ...
2 réflexions au sujet de « Générateur de Code Morse réalisé en HTML »
Il vous manque les symboles tiers et les chiffres, une vitesse de 15 a 20 et une pause de 3 secondes entre chaque code, dans le cas contraire cela est instable et trop rapide.
Exemple : wpm 20
Code corrigé comme demandé 😉
73