Move section marks calculation to view

Also try to fix section mark epsilon
This commit is contained in:
John Factotum
2023-11-02 16:10:40 +08:00
parent 7dcbc6921a
commit 2a6012d749
3 changed files with 26 additions and 27 deletions
+18 -17
View File
@@ -57,10 +57,18 @@ export class TOCProgress {
export class SectionProgress {
constructor(sections, sizePerLoc, sizePerTimeUnit) {
this.sizes = sections.map(s => s.linear === 'no' ? 0 : s.size)
this.sizes = sections.map(s => s.linear != 'no' && s.size > 0 ? s.size : 0)
this.sizePerLoc = sizePerLoc
this.sizePerTimeUnit = sizePerTimeUnit
this.sizeTotal = this.sizes.reduce((a, b) => a + b, 0)
this.sectionFractions = this.#getSectionFractions()
}
#getSectionFractions() {
const { sizeTotal } = this
const results = [0]
let sum = 0
for (const size of this.sizes) results.push((sum += size) / sizeTotal)
return results
}
// get progress given index of and fractions within a section
getProgress(index, fractionInSection, pageFraction = 0) {
@@ -91,22 +99,15 @@ export class SectionProgress {
// the inverse of `getProgress`
// get index of and fraction in section based on total fraction
getSection(fraction) {
if (fraction === 0) return [0, 0]
if (fraction === 1) return [this.sizes.length - 1, 1]
const { sizes, sizeTotal } = this
const target = fraction * sizeTotal
let index = -1
let fractionInSection = 0
let sum = 0
for (const [i, size] of sizes.entries()) {
const newSum = sum + size
if (newSum > target) {
index = i
fractionInSection = (target - sum) / size
break
}
sum = newSum
}
if (fraction <= 0) return [0, 0]
if (fraction >= 1) return [this.sizes.length - 1, 1]
fraction = fraction + Number.EPSILON
const { sizeTotal } = this
let index = this.sectionFractions.findIndex(x => x > fraction) - 1
if (index < 0) return [0, 0]
while (!this.sizes[index]) index++
const fractionInSection = (fraction - this.sectionFractions[index])
/ (this.sizes[index] / sizeTotal)
return [index, fractionInSection]
}
}
+2 -8
View File
@@ -211,17 +211,11 @@ class Reader {
slider.dir = book.dir
slider.addEventListener('input', e =>
this.view.goToFraction(parseFloat(e.target.value)))
const sizes = book.sections.filter(s => s.linear !== 'no').map(s => s.size)
if (sizes.length < 100) {
const total = sizes.reduce((a, b) => a + b, 0)
let sum = 0
for (const size of sizes.slice(0, -1)) {
sum += size
for (const fraction of this.view.getSectionFractions()) {
const option = document.createElement('option')
option.value = sum / total
option.value = fraction
$('#tick-marks').append(option)
}
}
document.addEventListener('keydown', this.#handleKeydown.bind(this))
+4
View File
@@ -327,6 +327,10 @@ export class View extends HTMLElement {
for (const { doc } of this.renderer.getContents())
doc.defaultView.getSelection().removeAllRanges()
}
getSectionFractions() {
return (this.#sectionProgress?.sectionFractions ?? [])
.map(x => x + Number.EPSILON)
}
getProgressOf(index, range) {
const tocItem = this.#tocProgress?.getProgress(index, range)
const pageItem = this.#pageProgress?.getProgress(index, range)