mirror of
https://github.com/genemecija/learn-morse-code.git
synced 2025-12-06 07:02:00 +01:00
Added iambic mode B
This commit is contained in:
parent
5b10049129
commit
b55462dd6d
10
README.md
10
README.md
|
|
@ -29,3 +29,13 @@ Type in the translator below the legend and see/listen to the Morse translation.
|
||||||
This web app was built using HTML, CSS, and ReactJS. It utilizes React hooks to manage state and component lifecycle.
|
This web app was built using HTML, CSS, and ReactJS. It utilizes React hooks to manage state and component lifecycle.
|
||||||
|
|
||||||
See it live here: https://genemecija.github.io/learn-morse-code/
|
See it live here: https://genemecija.github.io/learn-morse-code/
|
||||||
|
|
||||||
|
## Build Instructions
|
||||||
|
|
||||||
|
To build and run the project:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd src/
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
@ -39,7 +39,7 @@ export default React.memo(function Info() {
|
||||||
<center><img src={straight_key} alt="Straight Key" /></center>
|
<center><img src={straight_key} alt="Straight Key" /></center>
|
||||||
<p><b>Straight Keys</b> use a single button and generate tones when pressed down. Straight keys require greater accuracy as the length of dits, dahs, and spacing is completely under manual control.</p>
|
<p><b>Straight Keys</b> use a single button and generate tones when pressed down. Straight keys require greater accuracy as the length of dits, dahs, and spacing is completely under manual control.</p>
|
||||||
<center><img src={electronic_key} alt="Electronic Key"></img></center>
|
<center><img src={electronic_key} alt="Electronic Key"></img></center>
|
||||||
<p><b>Electronic Keys</b> use paddles that automatically generate dits and dahs when pressed. The Electronic Keyer used here is an Iambic keyer that uses two paddles–left paddle for dits, right paddle for dahs. Pressing both paddles simultaneously automatically alternates between dit and dah. Switch between the two paddles at the appropriate times to build letters in Morse code.</p>
|
<p><b>Electronic Keys</b> use paddles that automatically generate dits and dahs when pressed. The Electronic Keyer used here is an Iambic keyer that uses two paddles–left paddle for dits, right paddle for dahs. Pressing both paddles simultaneously automatically alternates between dit and dah. Mode B automatically adds an extra alternate dit or dah. Switch between the two paddles at the appropriate times to build letters in Morse code.</p>
|
||||||
|
|
||||||
<p>Check out <a href='https://www.youtube.com/watch?v=uEy4Wvy6uUg' target='_blank' rel="noopener noreferrer">this video</a> for a demonstration of the difference between Straight and Electronic keys.</p>
|
<p>Check out <a href='https://www.youtube.com/watch?v=uEy4Wvy6uUg' target='_blank' rel="noopener noreferrer">this video</a> for a demonstration of the difference between Straight and Electronic keys.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,36 @@ export default React.memo(function KeyTypePicker() {
|
||||||
|
|
||||||
function handleClick(e) {
|
function handleClick(e) {
|
||||||
setKeyType(e.target.id)
|
setKeyType(e.target.id)
|
||||||
|
switch (e.target.id)
|
||||||
let buttons = document.querySelector(".mode-picker#keyType #buttons").childNodes
|
{
|
||||||
buttons.forEach(button => {
|
case 'straight':
|
||||||
if (button.id === e.target.id) {
|
e.target.classList.add('selected');
|
||||||
button.classList.add('selected')
|
document.getElementById('electronic').classList.remove('selected')
|
||||||
} else { button.classList.remove('selected')}
|
document.querySelector('#morseButton').classList.remove('showPaddles')
|
||||||
})
|
document.querySelector('.paddle').classList.remove('showPaddles')
|
||||||
|
document.querySelector('.paddle#left').classList.remove('showPaddles')
|
||||||
if (e.target.id === 'electronic') {
|
document.querySelector('.paddle#right').classList.remove('showPaddles')
|
||||||
document.querySelector('#morseButton').classList.add('showPaddles')
|
document.getElementById('paddle-mode-buttons').style.visibility = 'hidden'
|
||||||
document.querySelector('.paddle').classList.add('showPaddles')
|
document.getElementById('morseButtonText').innerHTML = 'TAP BUTTON OR PRESS SPACEBAR'
|
||||||
document.querySelector('.paddle#left').classList.add('showPaddles')
|
break;
|
||||||
document.querySelector('.paddle#right').classList.add('showPaddles')
|
case 'electronic':
|
||||||
document.getElementById('morseButtonText').innerHTML = 'TAP/HOLD BUTTONS OR PRESS COMMA / PERIOD'
|
e.target.classList.add('selected');
|
||||||
} else {
|
document.getElementById('straight').classList.remove('selected')
|
||||||
document.querySelector('#morseButton').classList.remove('showPaddles')
|
document.querySelector('#morseButton').classList.add('showPaddles')
|
||||||
document.querySelector('.paddle').classList.remove('showPaddles')
|
document.querySelector('.paddle').classList.add('showPaddles')
|
||||||
document.querySelector('.paddle#left').classList.remove('showPaddles')
|
document.querySelector('.paddle#left').classList.add('showPaddles')
|
||||||
document.querySelector('.paddle#right').classList.remove('showPaddles')
|
document.querySelector('.paddle#right').classList.add('showPaddles')
|
||||||
document.getElementById('morseButtonText').innerHTML = 'TAP BUTTON OR PRESS SPACEBAR'
|
document.getElementById('paddle-mode-buttons').style.visibility = 'visible'
|
||||||
|
document.getElementById('morseButtonText').innerHTML = 'TAP/HOLD BUTTONS OR PRESS COMMA / PERIOD'
|
||||||
|
break
|
||||||
|
case 'modeA':
|
||||||
|
e.target.classList.add('selected')
|
||||||
|
document.getElementById('modeB').classList.remove('selected')
|
||||||
|
break;
|
||||||
|
case 'modeB':
|
||||||
|
e.target.classList.add('selected')
|
||||||
|
document.getElementById('modeA').classList.remove('selected')
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,7 +51,7 @@ export default React.memo(function KeyTypePicker() {
|
||||||
<div id="title">
|
<div id="title">
|
||||||
Key Type
|
Key Type
|
||||||
</div>
|
</div>
|
||||||
<div id="buttons">
|
<div id="key-type-buttons">
|
||||||
<button id="straight" onClick={handleClick}>
|
<button id="straight" onClick={handleClick}>
|
||||||
Straight Key
|
Straight Key
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -49,6 +59,18 @@ export default React.memo(function KeyTypePicker() {
|
||||||
Electronic Key
|
Electronic Key
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="paddle-mode-buttons">
|
||||||
|
<fieldset id="paddle-mode">
|
||||||
|
<legend>Paddle Mode</legend>
|
||||||
|
<button id="modeA" class="selected" onClick={handleClick}>
|
||||||
|
A
|
||||||
|
</button>
|
||||||
|
<button id="modeB" onClick={handleClick}>
|
||||||
|
B
|
||||||
|
</button>
|
||||||
|
<br />
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
@ -13,6 +13,23 @@ button {
|
||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: x-small;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
padding-bottom: 0.3em;
|
||||||
|
margin-top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#paddle-mode-buttons {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export default (function useElectronicKey() {
|
||||||
let queueRunning = false
|
let queueRunning = false
|
||||||
let queue = []
|
let queue = []
|
||||||
let pressedFirst = null
|
let pressedFirst = null
|
||||||
|
let lastPlayed = ''
|
||||||
|
|
||||||
// Timers setup
|
// Timers setup
|
||||||
let depressSyncTime
|
let depressSyncTime
|
||||||
|
|
@ -51,6 +52,7 @@ export default (function useElectronicKey() {
|
||||||
|
|
||||||
// Promisify playing Dits and Dahs
|
// Promisify playing Dits and Dahs
|
||||||
function play(ditDah) {
|
function play(ditDah) {
|
||||||
|
lastPlayed = ditDah
|
||||||
let playDuration = ((ditDah === '.') ? ditMaxTime : ditMaxTime*3)
|
let playDuration = ((ditDah === '.') ? ditMaxTime : ditMaxTime*3)
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -159,7 +161,11 @@ export default (function useElectronicKey() {
|
||||||
cleanup()
|
cleanup()
|
||||||
}
|
}
|
||||||
currentPromise = currentPromise.then(() => {
|
currentPromise = currentPromise.then(() => {
|
||||||
return playWithSpaces(localQueue[i])
|
var ditDah = localQueue[i]
|
||||||
|
if (ditDah)
|
||||||
|
{
|
||||||
|
return playWithSpaces(ditDah)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +243,6 @@ export default (function useElectronicKey() {
|
||||||
document.querySelector('.paddle#left').classList.remove('active')
|
document.querySelector('.paddle#left').classList.remove('active')
|
||||||
|
|
||||||
leftIsPressed = false
|
leftIsPressed = false
|
||||||
|
|
||||||
if (pressedFirst === 'left') { pressedFirst = null }
|
if (pressedFirst === 'left') { pressedFirst = null }
|
||||||
|
|
||||||
if (!depressSyncTimerRunning) { startDepressSyncTimer() }
|
if (!depressSyncTimerRunning) { startDepressSyncTimer() }
|
||||||
|
|
@ -252,6 +257,13 @@ export default (function useElectronicKey() {
|
||||||
if (!depressSyncTimerRunning) { startDepressSyncTimer() }
|
if (!depressSyncTimerRunning) { startDepressSyncTimer() }
|
||||||
else { stopDepressSyncTimer() }
|
else { stopDepressSyncTimer() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (paddlesReleasedSimultaneously && document.getElementById('modeB').classList.contains('selected'))
|
||||||
|
{
|
||||||
|
currentPromise = currentPromise.then(() => {
|
||||||
|
return playWithSpaces(lastPlayed == '.' ? '-' : '.')
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timer used to determine if both paddles are released within 10ms
|
// Timer used to determine if both paddles are released within 10ms
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue