Skip to content

fix(reader): 统一桌面端/移动端页面边距计算,为页边距 UI 做准备 - #679

Open
k6G52m4Dz75W wants to merge 1 commit into
codedogQBY:mainfrom
k6G52m4Dz75W:fix/reader-page-margin
Open

fix(reader): 统一桌面端/移动端页面边距计算,为页边距 UI 做准备#679
k6G52m4Dz75W wants to merge 1 commit into
codedogQBY:mainfrom
k6G52m4Dz75W:fix/reader-page-margin

Conversation

@k6G52m4Dz75W

Copy link
Copy Markdown
Contributor

背景

阅读器的页边距(page margin)目前是"隐藏能力":设置项 settings.pageMargin 早已存在于两端设置仓库中,但没有任何 UI 入口,且两端的计算逻辑都是临时拼凑的,导致这个值实际上无法被正确、统一地应用。

  • foliate-js 的 gap 属性一直是坏的(一个潜伏的回归 bug):attributeChangedCallbackcase 'gap'case 'margin' 混在一起,把 gap 的值写到 --_margin-*(四个页边距)上,而真正的列间距变量 --_gap 从未从属性更新,恒为 7% 默认值。结果是:所有调用方计算出的 gapPercent 都是死代码——设置了 gap 要么被忽略,要么把页边距污染成百分比。
  • 桌面端max-inline-size 用硬编码 760px + 固定 gap,完全不随 pageMargin 变化。
  • 移动端:用 margin / 393 的粗略启发式,且 gapPercent 因为上面的 bug 实际不生效。

本 PR 把两端的页面边距计算统一为同一套推导,修复潜伏的 gap bug,为后续在阅读器设置面板加入"页边距"滑块铺路——之后 UI 只需写入 settings.pageMargin 即可生效。

改动内容

1. foliate-js/paginator.js:修复 gap 属性语义(对齐上游)

case 'gap':
    this.#top.style.setProperty('--_gap', value)   // 之前误写成 --_margin-*
    this.render()
    break
case 'margin':
    this.#top.style.setProperty('--_margin-top', value)
    this.#top.style.setProperty('--_margin-right', value)
    this.#top.style.setProperty('--_margin-bottom', value)
    this.#top.style.setProperty('--_margin-left', value)
    this.render()
    break

Desktop + mobile shared page-margin calculation:
- foliate-js: the gap attribute was conflated with margin (case 'gap'
  set the four --_margin-* vars), so --_gap never updated from the attribute
  and stayed at its 7% default; the gapPercent computed by callers was dead.
  Restore upstream semantics: gap -> --_gap, margin -> the four --_margin-*.
- desktop (FoliateViewer): derive max-inline-size + gap from renderer.clientWidth
  (foliate resolves the gap % against it). A double spread is two columns of
  ONE iframe, so the center gutter = column-gap = effective gap / 2; solving
  gutter = margin and outer = margin + breathing room (paper = 99% of window,
  so pages never touch the window edges even at margin 0) yields
  g = 2M/(0.99H + M), max-inline = (paper - M + g.H)/2 for double and
  g = M/paper, max-inline = paper - M + g.H for single. No rounding -> exact.
- desktop: re-apply layout when pageMargin changes and on window resize.
- mobile (reader.template.html): replace the margin/393 heuristic with the
  same single-page formula via applyMobileReflowMargins (margin-top/bottom,
  margin-left/right 0, gap + max-inline from renderer.clientWidth); rebuilt
  reader.html.
@k6G52m4Dz75W

Copy link
Copy Markdown
Contributor Author

验证

移动端模拟验证(自建自包含测试页,跑在桌面 Chromium/Edge,与移动端 WebView2 同内核):

  • 生成一个单章测试 EPUB(中文正文),在 393×852(iPhone 尺寸)视口用 foliate-view 渲染
  • 应用 applyMobileReflowMargins原样逻辑,拖动页边距滑块,实测首个字形距屏幕左缘的内缩
pageMargin 实际内缩 期望值 (margin + 0.5% 宽度)
0 ~3px ~2px(偏差为浏览器亚像素取整的 ~1px,可忽略)
16 ~18px ~18px
80 ~83px ~82px

结论:

  • 边距随滑块线性且精确,取代旧的 margin / 393 硬编码启发式
  • pageMargin = 0 时文字不贴边(99% 纸张 + 0.5% 呼吸),与桌面端一致
  • 右侧略多出几 px 是段落末行排不满(整数字符放不下)的排版现象,非边距问题

桌面端:默认 pageMargin=40 即生效;margin 0/40/80 外距 = 中缝 = margin,四边均匀。

移动端真机(WebView2)建议在真实设备上再做一次确认。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant