Files
2026-09-09 14:47:29 +08:00

84 lines
2.7 KiB
JavaScript

const DEFAULT_COMIC_ART_ASPECT_RATIO = 16 / 9
const MIN_COMIC_ART_ASPECT_RATIO = 1.4
const MAX_COMIC_ART_ASPECT_RATIO = 3
function normalizeComicArtAspectRatio(page) {
const requested = Number(page && page.artAspectRatio)
if (
Number.isFinite(requested)
&& requested >= MIN_COMIC_ART_ASPECT_RATIO
&& requested <= MAX_COMIC_ART_ASPECT_RATIO
) {
return requested
}
return DEFAULT_COMIC_ART_ASPECT_RATIO
}
function getComicArtStageStyle(metrics, page) {
const safeMetrics = metrics || {}
const contentWidth = Math.max(
1,
Number(safeMetrics.windowWidth || 1)
- Number(safeMetrics.safeLeft || 0)
- Number(safeMetrics.safeRight || 0),
)
const contentHeight = Math.max(
1,
Number(safeMetrics.windowHeight || 1)
- Number(safeMetrics.topbarHeight || 0)
- Number(safeMetrics.safeBottom || 0),
)
const aspectRatio = normalizeComicArtAspectRatio(page)
if (safeMetrics.compactHeight) {
// A phone in landscape does not have enough height for a 16:9 picture
// plus an elder-readable caption below it. Compact pages therefore open
// like a two-page lianhuanhua spread: illustration on the left, caption
// paper on the right. Keep these numbers in lockstep with chapter.wxss.
const captionWidth = Math.max(190, contentWidth * 0.28)
const artColumnWidth = Math.max(1, contentWidth - captionWidth)
const artColumnPadding = 12
const availableWidth = Math.max(1, artColumnWidth - artColumnPadding)
const availableHeight = Math.max(1, contentHeight - artColumnPadding)
const artWidth = Math.max(
1,
Math.min(availableWidth, availableHeight * aspectRatio),
)
const artHeight = artWidth / aspectRatio
return [
`width:${Math.round(artWidth)}px`,
`height:${Math.round(artHeight)}px`,
].join(';')
}
// Keep this in lockstep with chapter.wxss:
// regular: minmax(0, 3fr) minmax(190px, 1fr)
// When the caption track reaches its minimum, the art receives the
// remainder. Calculating that exact height prevents max-height from
// compressing only the stage height and stretching a 16:9 illustration.
const proportionalArtHeight = contentHeight * 0.75
const captionMinimum = 190
const artRowHeight = Math.max(
1,
Math.min(
proportionalArtHeight,
contentHeight - captionMinimum,
),
)
const artWidth = Math.max(
1,
Math.min(contentWidth, artRowHeight * aspectRatio),
)
const artHeight = artWidth / aspectRatio
return [
`width:${Math.round(artWidth)}px`,
`height:${Math.round(artHeight)}px`,
].join(';')
}
module.exports = {
DEFAULT_COMIC_ART_ASPECT_RATIO,
normalizeComicArtAspectRatio,
getComicArtStageStyle,
}