Skip to content

Latest commit

 

History

History
97 lines (52 loc) · 16.2 KB

File metadata and controls

97 lines (52 loc) · 16.2 KB

阅读器

当前体验

生产阅读器只提供分页:点按两侧、左右拖动、键盘或辅助语义操作翻页,中间点按显示 / 隐藏工具栏。旧偏好中的滚动模式读取为分页,保留其余设置和进度;底层实验视口仍可用于开发,不是产品入口。

键盘左右方向键或 PageUp / PageDown 前后翻页,F2 显示 / 隐藏工具栏。原生阅读页支持鼠标滚轮翻页,一次连续滚动只触发一次翻页,双页按一组翻动;特殊 WebView 页面保留页内滚动。Esc 关闭目录、进度、设置弹层或图片预览;弹层打开时不翻动背后的正文。

页眉展示书名或实际卷名,避免使用文件节点的「标题」等占位名称;页脚显示本章进度。Android / iOS 阅读期间隐藏系统状态栏与导航栏,页脚同时显示时间和电量(无法读取电量时只显示时间)。工具栏覆盖在正文之上,显示 / 隐藏不改变分页。

目录在阅读页内以弹层打开:在线作品可在「卷内目录」(正文标题)与「分卷目录」之间切换,本地书显示全书目录;选择章节后本地 EPUB 可直接定位条目。进入设置和返回不应重置正文位置。

桌面阅读器使用全窗口 root 路由,目录、进度、设置和注释通过桌面面板呈现;移动端保留触摸弹层。面板开关不改变正文 viewport 或重建 WebView。弹层关闭与返回遵循最上层优先,图片预览返回后恢复阅读页。

排版

普通中文段落保持左对齐和自然字距,按当前字体与文字缩放测量整字宽度,正文区域最多收窄不足一字并左右居中;测量与绘制使用同一宽度。标题、图片及明确居中/右对齐不调整。标点和中英文混排仍可产生自然参差,不更改正文或持久阅读身份。

单页阅读区域最多宽 680 逻辑像素。普通正文在扣除页边距后可容纳两页(每页至少 500 逻辑像素、页间距 72)时自动并排显示,中缝以随主题变化的淡竖线区分。双页只取决于可用宽度,不区分平台:大屏平板(iPad / Android 横屏)与桌面宽窗同样进入双页,属预期行为;键盘、鼠标等桌面能力另行区分。先左后右,按一组两页翻动;窗口缩放按语义位置恢复。正文章节中的整页插图独占一栏,在该栏内垂直居中,可与相邻文字页或另一张插图组成双页;图片与图注均按实际栏宽测量和绘制。章末不足两页时右侧留空,不跨章节配对;末尾插图仍只占左栏。纯图片章节(包括只有一张图片的独立内容)与特殊 WebView 页面继续限宽居中单独展示,单页模式保持原行为。

设置 默认值 / 行为
正文字号 20 logical px
行高 1.6 倍字号
段间距 20 logical px
左右页边距 五档;适中以每侧 30 logical px 为基准,窄/宽分别多/少一字,极窄/极宽多/少两字
章节级标题 正文 1.4 倍、w700、行高 1.3;默认居中,上下留白
次级标题 正文 1.15 倍、w600,较小上下留白

标题留白随段距调整:章节级标题上下各 (段距 + 64) / 2,次级标题各 (段距 + 28) / 2。明确的右对齐保留。标题与后续正文在空间允许时一起排入下一页,避免标题独占页尾。长段落分块测量,大图按比例单页显示,不将一整章一次性布局。

在线普通中文段落在没有原始缩进时补首行两字缩进;已有前导空白、明确对齐、标题及跨页续段不重复添加。缩进只改变显示,不修改正文或语义身份。本地 EPUB 保留可识别的原始缩进 / 对齐。

EPUB 悬挂段落首行从普通起点开始,续行使用作者的 em 悬挂量;分页、双页续栏与内部切块不会重置首行。测量和绘制共用源文本范围与行框,尾部标签可同行靠右,放不下时另起行靠右,可随长段落跨页。窄栏或大字体下只收缩悬挂量,尽量留下四个当前字号的 em 供正文;宽度不足四 em 时取消悬挂,不缩小用户字号。标签过宽时按原文断行并保持右对齐。像素几何不持久化,样式变化通过完整内容值触发重排。

设置面板从底部弹出,只轻微压暗正文,便于实时预览。纸白 / 暖纸 / 夜间以对应纸色的色卡选择;「跟随系统」开启时系统深色自动用夜间,选择与当前系统明暗一致的色卡不会关闭跟随。面板只有一个「恢复默认」,重置阅读设置,保留已看过操作提示的状态;重置后可撤销,任何后续修改都会让撤销失效。偏好以 300ms 合并写入,关闭面板及生命周期节点刷新;失败保留预览和重试能力。

字号用滑块加两端的小 / 大「A」调节,行距、段间距使用加减按钮,步长分别为 1、0.1、2,按住连续调节;达到上下限禁用对应按钮。页边距五档使用当前字宽计算,旧数值就近映射档位,恢复默认回到适中。

EPUB 渲染

普通正文走原生分页,保留段落、标题、分隔线和图片。章节开头的最高级标题即使标成 h4 等,也可提升为章节级显示;不能只针对 h1 / h2 优化而遗漏实际文件。

原生正文图片可将高置信度白底文字/细线图映射到当前纸色与墨色。识别在有界缩略解码后进行,检查纸面、笔画、连续灰度/深色区域及彩边分布;这是保守启发式,照片、明显彩色内容、透明图或不确定结果保留原图。主题无关墨迹层与原图使用不同缓存键,共享解码缓存预算;切换纸色只改变绘制颜色,不重新上报尺寸。封面和原图预览保持原样,保存原图仍导出原始编码字节。

受限双列表格共用原生分页测量与绘制。同组左列取作者宽度与短标签实测宽度的较大值,右正文在当前栏内换行;跨页后左标签不重复。空白行折合前一记录的尾部间距,竖线随可见片段连续绘制,行间不叠加阅读器段距。栏宽无法容纳两列时整组回退可读文本,极短视口中的行尾空白限制在单页可用高度内。结构变化通过显式重新解析获取;图片纸色适配无需重新解析。

短扉页等特殊内容在满足受限条件时使用静态 WebView 保留竖排、定位、变换等样式;不是把整本 EPUB 交给网页渲染。资源内嵌、脚本关闭、外部请求禁用,具体限制见本地导入。特殊页按内容尺寸适配并考虑居中;超长内容可用滚轮或触摸在页内滚动,隐藏滚动条并禁用 WebView 越界回弹,不恢复产品的上下滚动阅读模式。

普通 EPUB 与在线正文支持原生上方 Ruby 注音,基字和注音作为同一换行单元,测量、绘制、系统字体缩放共用尺寸与基线。注音默认使用基字约一半的字号,组合宽于可用行宽时整体等比缩小,避免不可拆分的长注音阻塞分页。不实现竖排 Ruby、多层注音或复杂嵌套,解析时保留可读降级。常见直接基字、rb 与连续 rt 配对可保留;单组基字超过 64 码点或注音超过 256 码点时使用括注降级。

旧本地书通过重新解析获取注音结构;旧 JSON 继续可读,在线旧章节缓存保持离线可用并在允许联网时刷新。重新解析仅在根据新注音重建的整段括注文本与旧段唯一匹配时迁移精确基字位置,原位置落在括注内则恢复到对应基字末尾并标记近似;其他情况沿用通用迁移规则。

翻页与切章

翻页方式在阅读设置中选择:仿真(默认)、覆盖、平移、无动画;旧设置读取为仿真。章内翻页、切章和进入 / 离开完成页共用 PageTurnFrame / PageTurnSlot,因此遵循同一方式。计时共用 PaperTurnMotion:完整行程基准 280ms,仿真使用 easeOutCubic,覆盖与平移使用 easeOutQuart。拖动释放后按剩余距离折算时间,非零动画最低 80ms;选择无动画或减少动态效果时立即完成。

仿真为简化纸张折页:空白纸背、渐变、下层页投影与折痕高光,不截取正文作为背面,不做完整 3D 纸张变形;折痕向按住的位置倾斜,拖动靠下时下角先翻起,点按与键盘从页面中部翻。覆盖为新页从一侧滑入盖住旧页(倒翻时当前页滑出露出上一页),平移为两页并排移动;两者只在滑动页边缘加阴影。动画范围覆盖阅读页及页眉、页脚、页边距;正文裁剪使用整页坐标,避免只在中间 content box 内翻动。所有方式都移动实时组件,页面在翻页提交前后保持同一组件状态。

原生分页之间的相邻切章(正文、图片、表格和富文本)与章内共用跟手、释放和取消规则。方向在本次拖动中固定,比例与按压位置使用整页坐标;释放速度朝目标超过 600 logical px/s,或未快速反向释放且比例超过 0.28 时确认。系统取消始终回弹。目标就绪不会自动提交,拖到比例 1 但未释放也不激活目标会话;确认后保存当前真实位置,再从已显示的比例收尾,校验操作仍有效后交换章节、关闭旧会话并激活目标会话。

真实章末页可准备下一章首屏,真实章首页可准备上一章末屏,顺序沿用 readingOrder / spine;临时分页编号 0 不等同章首页。单页章节优先最近的拖动方向,缺省向后,无该方向邻章时选择另一侧。最多保留一个活动章节和一个可直接接管的候选。在线被动准备的正文与图片只读缓存,未命中不额外联网;明确开始翻页后使用正常读取策略,离线模式始终只读缓存。候选不保存进度、不改变活动预取位置、工具栏、焦点或窗口标题栏外观;取消或失败后不会因普通重建反复预热。

跨章加载时间不属于 280ms 动画时间。目标未就绪时保留当前真实页面,记录最新拖动比例;仍按住时就绪可接入当前手势,松手确认后仍需等待则显示可取消的等待条。未展示过目标时从原页状态开始收尾。保存失败保留原页与既有重试提示,准备失败或超时释放候选;取消、路由覆盖、应用后台及书籍失效均阻止迟到结果提交。

章内翻页与跨章视觉翻页共同保护图片布局:拖动、保存等待、收尾及回弹期间,两侧图片尺寸只记录,结束后仍存活的页面再按语义位置重排。未就绪候选可以完成首次排版;窗口、字号、缩放或内容排版值变化会撤销旧就绪状态,正在进行的跨章操作安全取消。纸色和墨色变化不重新请求章节。

涉及特殊 EPUB / WebView 的组合保持确认后准备并切换的路径,不创建隐藏 WebView 预加载池、不截图平台视图。其内部滚动、手势和所有权保持现有边界;平台视图裁剪、回弹和实际帧率仍需设备验证。完成页是单独的 UI 表面,不占用章节候选槽;WebView 末页与完成页之间采用确认后直接切换,保留同一个平台视图与滚动状态,不做跟手裁剪。

同一排版下保留已计算页面的轻量起止边界,完整页面仍只缓存当前阅读页组前后三组(单页或双页)。缓存淘汰后的倒翻复用已知边界。进度跳转、恢复和重排显示包含目标语义位置的正向分页,不将目标字强行设为页首;原始页内语义位置仍保留。未知目标从最近的已知正向边界分帧计算,首次深跳可能需要计算章节前缀;普通连续阅读仍按需计算。

倒翻进入上一章时,从章首沿正向分页链分帧寻找末页,使末页及后续倒翻边界与从章首阅读一致。每帧最多计算八页,达到约 4ms 后让出下一帧;准备期间仍显示当前章节,完成后才报告目标就绪和位置。字体、尺寸等排版条件变化会清空边界记录;图片尺寸更新后仍保持章末定位,直到用户翻页或跳转至其他位置。不持久化这些边界,也不提供全局页码。

全书进度与阅读完成

ReaderPosition.chapterFraction 只表示当前 ChapterContent 内的语义位置;沉浸页脚继续显示本章进度,工具栏显示「本章 N%」。进度面板标题右侧显示全书百分比,下面是章节标题、章节百分比及仅控制当前章的滑块;拖动不跨章、不加载其它正文。

全书进度是布局无关的近似:本地 EPUB/TXT 按主 readingOrder(缺省为主 Catalog 顺序)的规范化 block 数加权,辅助页不计入,特殊 HTML presentation 不重复计权;在线使用当前目录的 (ordinal + chapterFraction) / chapterCount,不为此下载全书。Reader 保存全书快照,书架、继续阅读和历史只读快照;旧记录未知时不显示百分比。重解析在迁移位置后按新结构重算。

当前章 completed 不等于全书完成。主阅读顺序最后一章已到末页后,用户再次向后翻才进入完成页;普通章节仍切到下一章,辅助文档不触发。完成页是 Reader UI 状态,不进入 Catalog 或内容模型;原生页和特殊 WebView 共用这条边界。向前翻、PageUp / 左键或反向滚轮回正文末页,继续向后翻无副作用。查看目录本身不清除终点状态;选择其它位置或重新阅读才随实际阅读更新。重新阅读回主阅读起点,返回书架前走既有刷新和失败重试流程。

原生真实末页与完成页双向共用跟手比例、整页按压位置和释放规则。临时预览、按住到比例 1、回弹均不写入终点;确认后按剩余行程收尾,再校验活动会话、目录依据和布局,才提交完成页显示状态并在原会话记录 EOF。重复取消共用回弹,路由覆盖、后台、失效和导航会撤销未提交操作;父状态确认不重播动画。返回末页只改变显示状态,继续向更早内容阅读或明确跳转才按原规则清除终点。完成页期间的字号、窗口和单双页变化让隐藏正文重新定位当前布局的真实末页组,不用旧页码恢复,也不覆盖已保存的 EOF。三种翻页期间合并保护图片尺寸更新,结束后由仍存活的页面应用。

完成页共享 Reader 工具栏、设置和命令权限:中间背景切换工具栏,工具栏已显示时背景点击只关闭;隐藏时左区返回末页,右区无下一页动作。按钮独立执行,顶部返回沿用原保存退出关系,正文「返回书架」仍走回书架动作。顶部显示与完成页一致的书名,底部仅提供目录和设置,不显示章节进度控件;保存与设置失败保留重试入口。工具栏状态在进入和离开时保持,打开目录或设置不清除完成状态。

完成页为上下工具栏保留稳定空间,短屏内容可纵向滚动;显示 / 隐藏工具栏不改变正文分页或完成页滚动位置。Android / iOS 隐藏工具栏时在原页脚位置显示时间和电量,显示工具栏时不叠加状态行;Windows 不增加手机状态行。两侧工具栏与页脚属于各自翻页图层,仅稳定活动页面接受控件输入、焦点和语义。

本地及可靠完结的在线作品显示「已读完」;连载显示「已读至最新」;停更或未知显示「已读至当前末尾」。终点状态绑定保存时的 Catalog revision 和章节身份;已加载的新在线目录会重算快照并使旧终点状态失效,因此新增章节后百分比可以降低。完成页不会临时联网查询完结状态。

位置与生命周期

持久化的是内容 revision、blockKey、块索引与块内 / 章节比例,不保存像素滚动偏移。改变字体、窗口或内容版本时按语义位置恢复;身份规则见领域模型。

进度写入使用会话 generation / sequence 拒绝晚写;未提交的目标章不抢占活动进度。展示标签约 4Hz 更新,不限制真实位置采样。退出和生命周期变化刷新待保存位置,写入失败不能假报已保存。

图片使用独立 lease 和有界解码缓存,释放页面需关闭消费者;章内重排不应重新下载整章。cacheOnly 阅读的正文和图片都不触发在线请求。