better chapter bars

This commit is contained in:
daniel-j 2018-03-15 22:57:14 +01:00
parent 82e80f8406
commit 5ea5e8185e
3 changed files with 31 additions and 14 deletions

View file

@ -74,7 +74,7 @@
"regenerator-runtime": "^0.11.1", "regenerator-runtime": "^0.11.1",
"removeNPMAbsolutePaths": "^1.0.4", "removeNPMAbsolutePaths": "^1.0.4",
"run-sequence": "^2.2.0", "run-sequence": "^2.2.0",
"standard": "^11.0.0", "standard": "^11.0.1",
"stylus": "^0.54.5", "stylus": "^0.54.5",
"stylus-loader": "^3.0.1", "stylus-loader": "^3.0.1",
"webpack": "^4.1.1", "webpack": "^4.1.1",

View file

@ -303,11 +303,13 @@ figure.youtube {
} }
} }
.chapterbars { svg.chapterbars {
width: 100%; width: 100%;
display: block; display: block;
height: 2em;
margin: 1em 0; margin: 1em 0;
page-break-inside: avoid;
break-inside: avoid;
-webkit-column-break-inside: avoid;
} }
.leftalign { .leftalign {

View file

@ -22,31 +22,46 @@ function prettyDate (d) {
return d.getDate() + nth(d) + ' ' + months[d.getMonth()].substring(0, 3) + ' ' + d.getFullYear() return d.getDate() + nth(d) + ' ' + months[d.getMonth()].substring(0, 3) + ' ' + d.getFullYear()
} }
function chapterBars (chapters, currentChapter = Infinity, highlightCurrent = false) { function chapterBars (chapters, currentChapter = -1, highlightCurrent = false) {
if (chapters.length === 1) return null if (chapters.length === 1) return null
let windowSize = 50
let wordCounts = [] let wordCounts = []
let highestWordCount = chapters.reduce((max, ch) => { let highestWordCount = chapters.reduce((max, ch) => {
wordCounts.push(ch.realWordCount) wordCounts.push(ch.realWordCount)
if (ch.realWordCount > max) return ch.realWordCount if (ch.realWordCount > max) return ch.realWordCount
return max return max
}, 0) }, 0)
if (wordCounts.length > windowSize && currentChapter >= 0 && currentChapter < wordCounts.length) {
windowSize = 30
let start = Math.ceil(Math.max(0, currentChapter - windowSize / 2 + 1))
start = Math.min(start, wordCounts.length - windowSize)
wordCounts.splice(0, start)
wordCounts.length = Math.min(wordCounts.length, windowSize)
currentChapter -= start
}
wordCounts = wordCounts.map((c) => c / highestWordCount) wordCounts = wordCounts.map((c) => c / highestWordCount)
const barWidth = 10 let barWidth = 9
const barSpacing = 2 let barSpacing = 2
const barCount = chapters.length let rowSpacing = 9
const barCount = Math.min(wordCounts.length, windowSize)
const rows = Math.floor(wordCounts.length / barCount) + 1
const rowHeight = 30 + rowSpacing
return m('svg.chapterbars', { return m('svg.chapterbars', {
viewBox: '0 0 ' + barCount * (barWidth + barSpacing) + ' 30', style: {height: rows * 3 + 'em'},
viewBox: '0 0 ' + barCount * (barWidth + barSpacing) + ' ' + rowHeight * rows,
xmlns: NS.SVG, xmlns: NS.SVG,
fill: 'currentColor' fill: 'currentColor'
}, wordCounts.map((c, i) => { }, wordCounts.map((c, i) => {
const percent = Math.ceil(c * 100) const x = i % barCount
let opacity = 0.5 const y = Math.floor(i / barCount)
const height = Math.ceil(c * (rowHeight - rowSpacing))
let opacity = 0.65
if (i === currentChapter && highlightCurrent) { if (i === currentChapter && highlightCurrent) {
opacity = 0.7 opacity = 0.85
} else if (i > currentChapter) { } else if (i > currentChapter) {
opacity = 0.25 opacity = 0.35
} }
return m('rect', {x: i * (barWidth + barSpacing), width: barWidth, y: (100 - percent) + '%', height: percent + '%', opacity}) return m('rect', {x: x * (barWidth + barSpacing), width: barWidth, y: y * rowHeight + (rowHeight - rowSpacing - height), height, opacity})
})) }))
} }
@ -299,7 +314,7 @@ export function createNav (ffc) {
m('nav.invisible', {'epub:type': 'toc'}, m('ol', list)), m('nav.invisible', {'epub:type': 'toc'}, m('ol', list)),
m('h3', 'Contents'), m('h3', 'Contents'),
m('ul#toc.hidden', prettyList), m('ul#toc.hidden', prettyList),
ffc.options.addChapterBars ? chapterBars(ffc.storyInfo.chapters, -1) : null ffc.options.addChapterBars ? chapterBars(ffc.storyInfo.chapters) : null
])) ]))
]) ])
, {strict: true}).then((navDocument) => { , {strict: true}).then((navDocument) => {