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, }