mirror of
https://github.com/john-okeefe/foliate-js.git
synced 2026-09-09 11:29:14 -04:00
FXL: add zoom setting
The value of the `zoom` attribute can be either `"fit-page"` (default), `"fit-width"`, or a number.
This commit is contained in:
+28
-9
@@ -30,6 +30,7 @@ const getViewport = (doc, viewport) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class FixedLayout extends HTMLElement {
|
export class FixedLayout extends HTMLElement {
|
||||||
|
static observedAttributes = ['zoom']
|
||||||
#root = this.attachShadow({ mode: 'closed' })
|
#root = this.attachShadow({ mode: 'closed' })
|
||||||
#observer = new ResizeObserver(() => this.#render())
|
#observer = new ResizeObserver(() => this.#render())
|
||||||
#spreads
|
#spreads
|
||||||
@@ -41,6 +42,7 @@ export class FixedLayout extends HTMLElement {
|
|||||||
#right
|
#right
|
||||||
#center
|
#center
|
||||||
#side
|
#side
|
||||||
|
#zoom
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@@ -52,10 +54,20 @@ export class FixedLayout extends HTMLElement {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
overflow: auto;
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
this.#observer.observe(this)
|
this.#observer.observe(this)
|
||||||
}
|
}
|
||||||
|
attributeChangedCallback(name, _, value) {
|
||||||
|
switch (name) {
|
||||||
|
case 'zoom':
|
||||||
|
this.#zoom = value !== 'fit-width' && value !== 'fit-page'
|
||||||
|
? parseFloat(value) : value
|
||||||
|
this.#render()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
async #createFrame({ index, src: srcOption }) {
|
async #createFrame({ index, src: srcOption }) {
|
||||||
const srcOptionIsString = typeof srcOption === 'string'
|
const srcOptionIsString = typeof srcOption === 'string'
|
||||||
const src = srcOptionIsString ? srcOption : srcOption?.src
|
const src = srcOptionIsString ? srcOption : srcOption?.src
|
||||||
@@ -102,15 +114,20 @@ export class FixedLayout extends HTMLElement {
|
|||||||
const blankWidth = left.width ?? right.width
|
const blankWidth = left.width ?? right.width
|
||||||
const blankHeight = left.height ?? right.height
|
const blankHeight = left.height ?? right.height
|
||||||
|
|
||||||
const scale = portrait || this.#center
|
const scale = typeof this.#zoom === 'number' && !isNaN(this.#zoom)
|
||||||
? Math.min(
|
? this.#zoom
|
||||||
width / (target.width ?? blankWidth),
|
: this.#zoom === 'fit-width' ? (portrait || this.#center
|
||||||
height / (target.height ?? blankHeight))
|
? width / (target.width ?? blankWidth)
|
||||||
: Math.min(
|
: width / ((left.width ?? blankWidth) + (right.width ?? blankWidth)))
|
||||||
width / ((left.width ?? blankWidth) + (right.width ?? blankWidth)),
|
: (portrait || this.#center
|
||||||
height / Math.max(
|
? Math.min(
|
||||||
left.height ?? blankHeight,
|
width / (target.width ?? blankWidth),
|
||||||
right.height ?? blankHeight))
|
height / (target.height ?? blankHeight))
|
||||||
|
: Math.min(
|
||||||
|
width / ((left.width ?? blankWidth) + (right.width ?? blankWidth)),
|
||||||
|
height / Math.max(
|
||||||
|
left.height ?? blankHeight,
|
||||||
|
right.height ?? blankHeight)))
|
||||||
|
|
||||||
const transform = frame => {
|
const transform = frame => {
|
||||||
let { element, iframe, width, height, blank, onZoom } = frame
|
let { element, iframe, width, height, blank, onZoom } = frame
|
||||||
@@ -128,6 +145,8 @@ export class FixedLayout extends HTMLElement {
|
|||||||
height: `${(height ?? blankHeight) * scale}px`,
|
height: `${(height ?? blankHeight) * scale}px`,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
display: 'block',
|
display: 'block',
|
||||||
|
flexShrink: '0',
|
||||||
|
marginBlock: 'auto',
|
||||||
})
|
})
|
||||||
if (portrait && frame !== target) {
|
if (portrait && frame !== target) {
|
||||||
element.style.display = 'none'
|
element.style.display = 'none'
|
||||||
|
|||||||
Reference in New Issue
Block a user