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 {
|
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]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,17 +211,11 @@ 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 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')
|
const option = document.createElement('option')
|
||||||
option.value = sum / total
|
option.value = fraction
|
||||||
$('#tick-marks').append(option)
|
$('#tick-marks').append(option)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('keydown', this.#handleKeydown.bind(this))
|
document.addEventListener('keydown', this.#handleKeydown.bind(this))
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user