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 { export class SectionProgress {
constructor(sections, sizePerLoc, sizePerTimeUnit) { 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.sizePerLoc = sizePerLoc
this.sizePerTimeUnit = sizePerTimeUnit this.sizePerTimeUnit = sizePerTimeUnit
this.sizeTotal = this.sizes.reduce((a, b) => a + b, 0) 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 // get progress given index of and fractions within a section
getProgress(index, fractionInSection, pageFraction = 0) { getProgress(index, fractionInSection, pageFraction = 0) {
@@ -91,22 +99,15 @@ export class SectionProgress {
// the inverse of `getProgress` // the inverse of `getProgress`
// get index of and fraction in section based on total fraction // get index of and fraction in section based on total fraction
getSection(fraction) { getSection(fraction) {
if (fraction === 0) return [0, 0] if (fraction <= 0) return [0, 0]
if (fraction === 1) return [this.sizes.length - 1, 1] if (fraction >= 1) return [this.sizes.length - 1, 1]
const { sizes, sizeTotal } = this fraction = fraction + Number.EPSILON
const target = fraction * sizeTotal const { sizeTotal } = this
let index = -1 let index = this.sectionFractions.findIndex(x => x > fraction) - 1
let fractionInSection = 0 if (index < 0) return [0, 0]
let sum = 0 while (!this.sizes[index]) index++
for (const [i, size] of sizes.entries()) { const fractionInSection = (fraction - this.sectionFractions[index])
const newSum = sum + size / (this.sizes[index] / sizeTotal)
if (newSum > target) {
index = i
fractionInSection = (target - sum) / size
break
}
sum = newSum
}
return [index, fractionInSection] return [index, fractionInSection]
} }
} }
+4 -10
View File
@@ -211,16 +211,10 @@ class Reader {
slider.dir = book.dir slider.dir = book.dir
slider.addEventListener('input', e => slider.addEventListener('input', e =>
this.view.goToFraction(parseFloat(e.target.value))) this.view.goToFraction(parseFloat(e.target.value)))
const sizes = book.sections.filter(s => s.linear !== 'no').map(s => s.size) for (const fraction of this.view.getSectionFractions()) {
if (sizes.length < 100) { const option = document.createElement('option')
const total = sizes.reduce((a, b) => a + b, 0) option.value = fraction
let sum = 0 $('#tick-marks').append(option)
for (const size of sizes.slice(0, -1)) {
sum += size
const option = document.createElement('option')
option.value = sum / total
$('#tick-marks').append(option)
}
} }
document.addEventListener('keydown', this.#handleKeydown.bind(this)) 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()) for (const { doc } of this.renderer.getContents())
doc.defaultView.getSelection().removeAllRanges() doc.defaultView.getSelection().removeAllRanges()
} }
getSectionFractions() {
return (this.#sectionProgress?.sectionFractions ?? [])
.map(x => x + Number.EPSILON)
}
getProgressOf(index, range) { getProgressOf(index, range) {
const tocItem = this.#tocProgress?.getProgress(index, range) const tocItem = this.#tocProgress?.getProgress(index, range)
const pageItem = this.#pageProgress?.getProgress(index, range) const pageItem = this.#pageProgress?.getProgress(index, range)