lokalnie gradle dziala
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
// Nauka Czytania
|
||||
;(function () {
|
||||
// ms between line advances for each speed level (0 = manual)
|
||||
const SPEEDS_MS = [0, 3500, 2000, 1000]
|
||||
const SPEED_LABELS = ['Pauza', 'Wolno', 'Średnio', 'Szybko']
|
||||
|
||||
let yOffset = 0
|
||||
let lineH = 80 // recalculated after render
|
||||
let maxOffset = 0
|
||||
let speedIdx = 0
|
||||
let autoTimer = null
|
||||
|
||||
const listWrap = document.getElementById('list-wrap')
|
||||
const readWrap = document.getElementById('read-wrap')
|
||||
const textList = document.getElementById('text-list')
|
||||
const customInput = document.getElementById('custom-input')
|
||||
const customStartBtn = document.getElementById('custom-start-btn')
|
||||
const readBackBtn = document.getElementById('read-back-btn')
|
||||
const readTitleEl = document.getElementById('read-title')
|
||||
const speedBtn = document.getElementById('speed-btn')
|
||||
const readViewport = document.getElementById('read-viewport')
|
||||
const readTextEl = document.getElementById('read-text')
|
||||
const nextLineBtn = document.getElementById('next-line-btn')
|
||||
let progressBar = null
|
||||
|
||||
// ── Load text list from dyktanda.json ────────────────────────────────────
|
||||
fetch('json/dyktanda.json')
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
data.forEach(item => {
|
||||
const btn = document.createElement('button')
|
||||
btn.className = 'list-item-btn'
|
||||
btn.textContent = item.name
|
||||
btn.addEventListener('click', () => startReading(item.name, item.text))
|
||||
textList.appendChild(btn)
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
textList.innerHTML = '<p style="color:var(--muted);padding:8px 0">Nie udało się wczytać tekstów.</p>'
|
||||
})
|
||||
|
||||
customStartBtn.addEventListener('click', () => {
|
||||
const txt = customInput.value.trim()
|
||||
if (!txt) return
|
||||
startReading('Własny', txt)
|
||||
})
|
||||
|
||||
// ── Start reading ─────────────────────────────────────────────────────────
|
||||
function startReading(title, text) {
|
||||
yOffset = 0
|
||||
speedIdx = 0
|
||||
clearInterval(autoTimer)
|
||||
autoTimer = null
|
||||
|
||||
readTitleEl.textContent = title
|
||||
readTextEl.textContent = text
|
||||
readTextEl.style.transform = 'translateY(0)'
|
||||
speedBtn.textContent = SPEED_LABELS[0]
|
||||
progressBar.style.width = '0%'
|
||||
|
||||
listWrap.classList.add('hidden')
|
||||
readWrap.classList.remove('hidden')
|
||||
|
||||
// measure real line height after layout
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
const cs = getComputedStyle(readTextEl)
|
||||
const lhVal = cs.lineHeight
|
||||
lineH = (lhVal === 'normal')
|
||||
? parseFloat(cs.fontSize) * 1.35
|
||||
: parseFloat(lhVal)
|
||||
|
||||
maxOffset = Math.max(0, readTextEl.offsetHeight - lineH)
|
||||
updateNextBtn()
|
||||
updateProgressBar()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// ── Back to list ──────────────────────────────────────────────────────────
|
||||
readBackBtn.addEventListener('click', () => {
|
||||
const active = yOffset > 0 || autoTimer !== null
|
||||
if (active && !confirm('Wrócić do listy tekstów?')) return
|
||||
clearInterval(autoTimer)
|
||||
autoTimer = null
|
||||
readWrap.classList.add('hidden')
|
||||
listWrap.classList.remove('hidden')
|
||||
// Reset speed to manual on exit
|
||||
speedIdx = 0;
|
||||
})
|
||||
|
||||
// ── Speed selector ────────────────────────────────────────────────────────
|
||||
speedBtn.addEventListener('click', () => {
|
||||
clearInterval(autoTimer)
|
||||
autoTimer = null
|
||||
speedIdx = (speedIdx + 1) % SPEEDS_MS.length
|
||||
speedBtn.textContent = SPEED_LABELS[speedIdx]
|
||||
if (SPEEDS_MS[speedIdx] > 0 && yOffset < maxOffset) {
|
||||
autoTimer = setInterval(advanceLine, SPEEDS_MS[speedIdx])
|
||||
}
|
||||
})
|
||||
|
||||
// ── Manual line advance ───────────────────────────────────────────────────
|
||||
nextLineBtn.addEventListener('click', advanceLine)
|
||||
|
||||
// ── Core scroll logic ─────────────────────────────────────────────────────
|
||||
function advanceLine() {
|
||||
if (yOffset >= maxOffset) {
|
||||
stopAutoAtEnd()
|
||||
return
|
||||
}
|
||||
yOffset = Math.min(yOffset + lineH, maxOffset)
|
||||
readTextEl.style.transform = `translateY(${-yOffset}px)`
|
||||
updateNextBtn()
|
||||
updateProgressBar()
|
||||
if (yOffset >= maxOffset) stopAutoAtEnd()
|
||||
}
|
||||
|
||||
function stopAutoAtEnd() {
|
||||
if (autoTimer !== null) {
|
||||
clearInterval(autoTimer)
|
||||
autoTimer = null
|
||||
speedIdx = 0
|
||||
speedBtn.textContent = SPEED_LABELS[0]
|
||||
}
|
||||
updateNextBtn()
|
||||
}
|
||||
|
||||
function updateNextBtn() {
|
||||
nextLineBtn.disabled = yOffset >= maxOffset
|
||||
}
|
||||
|
||||
function updateProgressBar() {
|
||||
const progress = maxOffset > 0 ? (yOffset / maxOffset) * 100 : 100
|
||||
if (!progressBar) progressBar = document.getElementById('read-progress-bar-inner')
|
||||
if (progressBar) progressBar.style.width = `${progress}%`
|
||||
}
|
||||
})()
|
||||
Reference in New Issue
Block a user