Added iambic mode B

This commit is contained in:
Ashley Feniello 2022-08-06 11:25:25 -07:00
parent 5b10049129
commit b55462dd6d
5 changed files with 85 additions and 24 deletions

View file

@ -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
```

View file

@ -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 paddlesleft 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 paddlesleft 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>

View file

@ -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>
) )
}) })

View file

@ -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;

View file

@ -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