Paginator: prevent spread in portrait

Or, for vertical writing, in landscape
This commit is contained in:
John Factotum
2024-04-27 16:14:36 +08:00
parent 28a757e5bb
commit b7ff640943
2 changed files with 43 additions and 25 deletions
+1 -1
View File
@@ -179,7 +179,7 @@ The layout can be configured by setting the following attributes:
- `gap`: a CSS `<percentage>`. The size of the space between columns, relative to page size.
- `max-inline-size`: a CSS `<length>`. The unit must be `px`. The maximum inline size of the text (column width in paginated mode).
- `max-block-size`: same as above, but for the size in the block direction.
- `max-column-count`: integer. The maximum number of columns. Has no effect in scrolled mode.
- `max-column-count`: integer. The maximum number of columns. Has no effect in scrolled mode, or when the orientation of the renderer element is `portrait` (or, for vertical writing, `landscape`).
(Note: there's no JS property API. You must use `.setAttribute()`.)
+42 -24
View File
@@ -376,6 +376,7 @@ export class Paginator extends HTMLElement {
]
#root = this.attachShadow({ mode: 'closed' })
#observer = new ResizeObserver(() => this.render())
#top
#background
#container
#header
@@ -399,21 +400,27 @@ export class Paginator extends HTMLElement {
super()
this.#root.innerHTML = `<style>
:host {
display: block;
container-type: size;
}
:host, #top {
box-sizing: border-box;
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
}
#top {
--_gap: 7%;
--_margin: 48px;
--_max-inline-size: 720px;
--_max-block-size: 1440px;
--_max-column-count: 2;
--_vertical: 0;
--_max-column-count-portrait: 1;
--_max-column-count-spread: var(--_max-column-count);
--_half-gap: calc(var(--_gap) / 2);
--_max-width: calc(
var(--_vertical) * var(--_max-block-size)
+ (1 - var(--_vertical)) * var(--_max-inline-size) * var(--_max-column-count)
);
--_max-height: calc(
var(--_vertical) * var(--_max-inline-size) * var(--_max-column-count)
+ (1 - var(--_vertical)) * var(--_max-block-size)
);
--_max-width: calc(var(--_max-inline-size) * var(--_max-column-count-spread));
--_max-height: var(--_max-block-size);
display: grid;
grid-template-columns:
minmax(var(--_half-gap), 1fr)
@@ -423,11 +430,19 @@ export class Paginator extends HTMLElement {
minmax(var(--_margin), 1fr)
minmax(0, var(--_max-height))
minmax(var(--_margin), 1fr);
box-sizing: border-box;
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
&.vertical {
--_max-column-count-spread: var(--_max-column-count-portrait);
--_max-width: var(--_max-block-size);
--_max-height: calc(var(--_max-inline-size) * var(--_max-column-count-spread));
}
@container (orientation: portrait) {
& {
--_max-column-count-spread: var(--_max-column-count-portrait);
}
&.vertical {
--_max-column-count-spread: var(--_max-column-count);
}
}
}
#background {
grid-column-start: 1;
@@ -475,12 +490,15 @@ export class Paginator extends HTMLElement {
opacity: .6;
}
</style>
<div id="background" part="filter"></div>
<div id="header"></div>
<div id="container"></div>
<div id="footer"></div>
<div id="top">
<div id="background" part="filter"></div>
<div id="header"></div>
<div id="container"></div>
<div id="footer"></div>
</div>
`
this.#top = this.#root.getElementById('top')
this.#background = this.#root.getElementById('background')
this.#container = this.#root.getElementById('container')
this.#header = this.#root.getElementById('header')
@@ -519,11 +537,11 @@ export class Paginator extends HTMLElement {
case 'margin':
case 'max-block-size':
case 'max-column-count':
this.style.setProperty('--_' + name, value)
this.#top.style.setProperty('--_' + name, value)
break
case 'max-inline-size':
// needs explicit `render()` as it doesn't necessarily resize
this.style.setProperty('--_' + name, value)
this.#top.style.setProperty('--_' + name, value)
this.render()
break
}
@@ -547,7 +565,7 @@ export class Paginator extends HTMLElement {
#beforeRender({ vertical, rtl, background }) {
this.#vertical = vertical
this.#rtl = rtl
this.style.setProperty('--_vertical', vertical ? 1 : 0)
this.#top.classList.toggle('vertical', vertical)
// set background to `doc` background
// this is needed because the iframe does not fill the whole element
@@ -556,9 +574,9 @@ export class Paginator extends HTMLElement {
const { width, height } = this.#container.getBoundingClientRect()
const size = vertical ? height : width
const style = getComputedStyle(this)
const style = getComputedStyle(this.#top)
const maxInlineSize = parseFloat(style.getPropertyValue('--_max-inline-size'))
const maxColumnCount = parseInt(style.getPropertyValue('--_max-column-count'))
const maxColumnCount = parseInt(style.getPropertyValue('--_max-column-count-spread'))
const margin = parseFloat(style.getPropertyValue('--_margin'))
this.#margin = margin
@@ -586,7 +604,7 @@ export class Paginator extends HTMLElement {
if (flow === 'scrolled') {
// FIXME: vertical-rl only, not -lr
this.setAttribute('dir', vertical ? 'rtl' : 'ltr')
this.style.padding = '0'
this.#top.style.padding = '0'
const columnWidth = maxInlineSize
this.heads = null