feat: mode-aware WPM ceiling — Sentence/Paragraph now go up to 3000 WPM (v1.1.1)
The WPM slider's maximum value now adapts to the active reading mode: - Word mode: 1500 WPM ceiling (human single-word recognition limit) - Sentence / Paragraph modes: 3000 WPM ceiling Rationale: in chunk modes, "WPM" controls auto-advance timing across larger display units. A 20-word sentence at 3000 WPM still gets ~400 ms of display time — well within visual-recognition comfort and suitable for skim-pass reading of already-familiar material. Switching back to Word mode auto-clamps the current value down to 1500 to prevent accidentally-illegible word-mode playback. The `+` keyboard shortcut now respects the mode-specific ceiling instead of being hardcoded to 1500.
This commit is contained in:
@@ -9,6 +9,25 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/) — versi
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [1.1.1] — 2026-05-27
|
||||||
|
|
||||||
|
### Changed — Mode-aware WPM ceiling
|
||||||
|
|
||||||
|
The WPM slider's maximum value now adapts to the active reading mode:
|
||||||
|
|
||||||
|
- **Word** mode: 1500 WPM ceiling (human single-word recognition limit — beyond ~25 ms per word the brain stops registering individual words)
|
||||||
|
- **Sentence** and **Paragraph** modes: 3000 WPM ceiling. In chunk modes the "WPM" controls auto-advance timing across larger display units, so higher values still produce comprehensible reading speeds (a 20-word sentence at 3000 WPM still gets ~400 ms of display time, which is well within visual-recognition comfort)
|
||||||
|
|
||||||
|
Switching from a high-WPM chunk mode back to Word mode automatically clamps the current value down to 1500, preventing accidentally-illegible word-mode playback.
|
||||||
|
|
||||||
|
The `+` keyboard shortcut now respects the mode-specific ceiling.
|
||||||
|
|
||||||
|
### Why this matters
|
||||||
|
|
||||||
|
For skim-pass reading on long thesis papers, the previous 1500 WPM cap in Sentence mode was too conservative. With a 20-word sentence at 1500 WPM the display held each sentence for ~1 s — comfortable but slower than necessary for already-known territory. 3000 WPM cuts that to ~400 ms, suitable for the Preview / Postview phases of structured reading (preview chapters, scan for known concepts, identify sections that warrant a slower second-pass read).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [1.1.0] — 2026-05-27
|
## [1.1.0] — 2026-05-27
|
||||||
|
|
||||||
### Added — Sentence and Paragraph reading modes
|
### Added — Sentence and Paragraph reading modes
|
||||||
|
|||||||
+17
-2
@@ -250,7 +250,7 @@ textarea:focus {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="meta" id="meta">Paste text below, drag a .txt file in, then press Play</span>
|
<span class="meta" id="meta">Paste text below, drag a .txt file in, then press Play</span>
|
||||||
<span class="version">v1.1</span>
|
<span class="version">v1.1.1</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stage mode-word" id="stage">
|
<div class="stage mode-word" id="stage">
|
||||||
@@ -513,11 +513,26 @@ textarea:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ─── Mode switching ────────────────────────────────────────────
|
// ─── Mode switching ────────────────────────────────────────────
|
||||||
|
// Mode-aware WPM ceiling. Word mode caps at 1500 — beyond that, the
|
||||||
|
// brain can't register single words faster than ~25ms per word. But
|
||||||
|
// Sentence and Paragraph modes display whole chunks at once; "WPM"
|
||||||
|
// there controls auto-advance timing, so values up to 3000 are
|
||||||
|
// genuinely useful for skim-reading (a 20-word sentence at 3000 WPM
|
||||||
|
// still gets ~400ms of display, which is comprehensible).
|
||||||
|
const WPM_MAX = { word: 1500, sentence: 3000, paragraph: 3000 };
|
||||||
|
|
||||||
function applyMode() {
|
function applyMode() {
|
||||||
stage.className = `stage mode-${mode}`;
|
stage.className = `stage mode-${mode}`;
|
||||||
[...modeToggle.querySelectorAll('button')].forEach(b => {
|
[...modeToggle.querySelectorAll('button')].forEach(b => {
|
||||||
b.classList.toggle('active', b.dataset.mode === mode);
|
b.classList.toggle('active', b.dataset.mode === mode);
|
||||||
});
|
});
|
||||||
|
// Adjust the WPM ceiling for the current mode + clamp current value if it exceeds
|
||||||
|
const newMax = WPM_MAX[mode] || 1500;
|
||||||
|
wpmSlider.max = newMax;
|
||||||
|
if (parseInt(wpmSlider.value) > newMax) {
|
||||||
|
wpmSlider.value = newMax;
|
||||||
|
wpmVal.textContent = newMax;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function setMode(newMode) {
|
function setMode(newMode) {
|
||||||
if (newMode === mode) return;
|
if (newMode === mode) return;
|
||||||
@@ -567,7 +582,7 @@ textarea:focus {
|
|||||||
else if (k === '2') { setMode('sentence'); }
|
else if (k === '2') { setMode('sentence'); }
|
||||||
else if (k === '3') { setMode('paragraph'); }
|
else if (k === '3') { setMode('paragraph'); }
|
||||||
else if (k === '+' || k === '=') {
|
else if (k === '+' || k === '=') {
|
||||||
wpmSlider.value = Math.min(1500, parseInt(wpmSlider.value) + 50);
|
wpmSlider.value = Math.min(parseInt(wpmSlider.max), parseInt(wpmSlider.value) + 50);
|
||||||
wpmVal.textContent = wpmSlider.value;
|
wpmVal.textContent = wpmSlider.value;
|
||||||
updateMeta();
|
updateMeta();
|
||||||
save();
|
save();
|
||||||
|
|||||||
Reference in New Issue
Block a user