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. - `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-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-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()`.) (Note: there's no JS property API. You must use `.setAttribute()`.)
+38 -20
View File
@@ -376,6 +376,7 @@ export class Paginator extends HTMLElement {
] ]
#root = this.attachShadow({ mode: 'closed' }) #root = this.attachShadow({ mode: 'closed' })
#observer = new ResizeObserver(() => this.render()) #observer = new ResizeObserver(() => this.render())
#top
#background #background
#container #container
#header #header
@@ -399,21 +400,27 @@ export class Paginator extends HTMLElement {
super() super()
this.#root.innerHTML = `<style> this.#root.innerHTML = `<style>
:host { :host {
display: block;
container-type: size;
}
:host, #top {
box-sizing: border-box;
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
}
#top {
--_gap: 7%; --_gap: 7%;
--_margin: 48px; --_margin: 48px;
--_max-inline-size: 720px; --_max-inline-size: 720px;
--_max-block-size: 1440px; --_max-block-size: 1440px;
--_max-column-count: 2; --_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); --_half-gap: calc(var(--_gap) / 2);
--_max-width: calc( --_max-width: calc(var(--_max-inline-size) * var(--_max-column-count-spread));
var(--_vertical) * var(--_max-block-size) --_max-height: 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)
);
display: grid; display: grid;
grid-template-columns: grid-template-columns:
minmax(var(--_half-gap), 1fr) minmax(var(--_half-gap), 1fr)
@@ -423,11 +430,19 @@ export class Paginator extends HTMLElement {
minmax(var(--_margin), 1fr) minmax(var(--_margin), 1fr)
minmax(0, var(--_max-height)) minmax(0, var(--_max-height))
minmax(var(--_margin), 1fr); minmax(var(--_margin), 1fr);
box-sizing: border-box; &.vertical {
position: relative; --_max-column-count-spread: var(--_max-column-count-portrait);
overflow: hidden; --_max-width: var(--_max-block-size);
width: 100%; --_max-height: calc(var(--_max-inline-size) * var(--_max-column-count-spread));
height: 100%; }
@container (orientation: portrait) {
& {
--_max-column-count-spread: var(--_max-column-count-portrait);
}
&.vertical {
--_max-column-count-spread: var(--_max-column-count);
}
}
} }
#background { #background {
grid-column-start: 1; grid-column-start: 1;
@@ -475,12 +490,15 @@ export class Paginator extends HTMLElement {
opacity: .6; opacity: .6;
} }
</style> </style>
<div id="top">
<div id="background" part="filter"></div> <div id="background" part="filter"></div>
<div id="header"></div> <div id="header"></div>
<div id="container"></div> <div id="container"></div>
<div id="footer"></div> <div id="footer"></div>
</div>
` `
this.#top = this.#root.getElementById('top')
this.#background = this.#root.getElementById('background') this.#background = this.#root.getElementById('background')
this.#container = this.#root.getElementById('container') this.#container = this.#root.getElementById('container')
this.#header = this.#root.getElementById('header') this.#header = this.#root.getElementById('header')
@@ -519,11 +537,11 @@ export class Paginator extends HTMLElement {
case 'margin': case 'margin':
case 'max-block-size': case 'max-block-size':
case 'max-column-count': case 'max-column-count':
this.style.setProperty('--_' + name, value) this.#top.style.setProperty('--_' + name, value)
break break
case 'max-inline-size': case 'max-inline-size':
// needs explicit `render()` as it doesn't necessarily resize // needs explicit `render()` as it doesn't necessarily resize
this.style.setProperty('--_' + name, value) this.#top.style.setProperty('--_' + name, value)
this.render() this.render()
break break
} }
@@ -547,7 +565,7 @@ export class Paginator extends HTMLElement {
#beforeRender({ vertical, rtl, background }) { #beforeRender({ vertical, rtl, background }) {
this.#vertical = vertical this.#vertical = vertical
this.#rtl = rtl this.#rtl = rtl
this.style.setProperty('--_vertical', vertical ? 1 : 0) this.#top.classList.toggle('vertical', vertical)
// set background to `doc` background // set background to `doc` background
// this is needed because the iframe does not fill the whole element // 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 { width, height } = this.#container.getBoundingClientRect()
const size = vertical ? height : width const size = vertical ? height : width
const style = getComputedStyle(this) const style = getComputedStyle(this.#top)
const maxInlineSize = parseFloat(style.getPropertyValue('--_max-inline-size')) 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')) const margin = parseFloat(style.getPropertyValue('--_margin'))
this.#margin = margin this.#margin = margin
@@ -586,7 +604,7 @@ export class Paginator extends HTMLElement {
if (flow === 'scrolled') { if (flow === 'scrolled') {
// FIXME: vertical-rl only, not -lr // FIXME: vertical-rl only, not -lr
this.setAttribute('dir', vertical ? 'rtl' : 'ltr') this.setAttribute('dir', vertical ? 'rtl' : 'ltr')
this.style.padding = '0' this.#top.style.padding = '0'
const columnWidth = maxInlineSize const columnWidth = maxInlineSize
this.heads = null this.heads = null