mirror of
https://github.com/john-okeefe/foliate-js.git
synced 2026-09-09 11:29:14 -04:00
Move section marks calculation to view
Also try to fix section mark epsilon
This commit is contained in:
+18
-17
@@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,16 +211,10 @@ 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
|
||||
const option = document.createElement('option')
|
||||
option.value = sum / total
|
||||
$('#tick-marks').append(option)
|
||||
}
|
||||
for (const fraction of this.view.getSectionFractions()) {
|
||||
const option = document.createElement('option')
|
||||
option.value = fraction
|
||||
$('#tick-marks').append(option)
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', this.#handleKeydown.bind(this))
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user