Koodo Reader阅读体验优化技术
Koodo Reader 是一款功能丰富的电子书阅读器,通过自定义阅读界面与主题系统、文本转语音(TTS)功能、书签笔记高亮系统以及多模式布局与排版优化技术,为用户提供高度个性化的阅读体验。文章详细分析了其架构设计、核心功能实现和技术细节,包括主题颜色系统、语音合成引擎、数据模型架构和响应式布局等关键技术。
自定义阅读界面与主题系统
Koodo Reader 提供了强大的自定义阅读界面功能,让用户可以根据个人喜好和阅读环境调整阅读体验。系统内置了丰富的主题配置选项,支持从字体样式到背景颜色的全方位自定义。
主题系统架构
Koodo Reader 的主题系统采用分层架构设计,通过 localStorage 存储用户配置,实现了配置的持久化和快速读取。系统通过 StorageUtil 工具类统一管理所有阅读配置,确保配置的一致性和可靠性。
classDiagram
class StorageUtil {
+getReaderConfig(key: string)
+setReaderConfig(key: string, value: string)
+getKookitConfig(key: string)
+setKookitConfig(key: string, value: string)
}
class StyleUtil {
+getCustomCss()
+getTextStyle()
+getThemeStyle()
}
class ThemeUtil {
+setThemes(themeName: string)
+clear(themeName: string)
+getThemes()
}
StorageUtil --> StyleUtil : 提供配置数据
StorageUtil --> ThemeUtil : 管理主题配置
StyleUtil --> ThemeUtil : 应用主题样式
核心配置参数
系统支持以下主要自定义配置选项:
| 配置项 | 数据类型 | 默认值 | 功能描述 |
|---|---|---|---|
fontSize |
string | "17" | 字体大小设置 |
fontFamily |
string | "Built-in font" | 字体家族选择 |
backgroundColor |
string | "rgba(255,255,255,1)" | 阅读背景颜色 |
themeColor |
string | "default" | 主题颜色方案 |
isOSNight |
string | 系统检测 | 夜间模式状态 |
appSkin |
string | "system" | 应用皮肤设置 |
主题颜色系统
Koodo Reader 内置了多种预设主题颜色,每种主题都包含完整的配色方案:
export const themeList = [
{
id: 0,
color: "rgba(75, 75, 75, 1)",
name: "default",
title: "Default",
},
{
id: 1,
color: "rgba(1, 121, 202, 1)",
name: "blue",
title: "Blue",
},
{
id: 2,
color: "rgba(0, 143, 145, 1)",
name: "green",
title: "Green",
},
{
id: 3,
color: "rgba(241, 100, 100, 1)",
name: "red",
title: "Red",
},
{
id: 4,
color: "rgba(104, 103, 209, 1)",
name: "purple",
title: "Purple",
},
];
背景颜色选项
系统提供了多种背景颜色预设,满足不同阅读场景的需求:
export const backgroundList = [
"rgba(255,255,255,1)", // 纯白色背景
"rgba(44,47,49,1)", // 深色背景
"rgba(233, 216, 188,1)", // 羊皮纸色背景
"rgba(197, 231, 207,1)", // 护眼绿色背景
];
export const textList = [
"rgba(0,0,0,1)", // 黑色文字
"rgba(255,255,255,1)", // 白色文字
"rgba(89, 68, 41,1)", // 棕色文字
"rgba(54, 80, 62,1)", // 深绿色文字
];
样式应用机制
Koodo Reader 通过 StyleUtil 类动态生成和应用CSS样式,实现实时预览效果:
// 获取自定义CSS样式
getCustomCss() {
return `font-size: ${
StorageUtil.getReaderConfig("fontSize") || 17
}px !important;line-height: ${
StorageUtil.getReaderConfig("lineHeight") || 1.5
} !important;text-indent: ${
StorageUtil.getReaderConfig("textIndent") || 0
}em !important;letter-spacing: ${
StorageUtil.getReaderConfig("letterSpacing") || 0
}px !important;margin-bottom: ${
StorageUtil.getReaderConfig("paragraphMargin") || 0
}px !important;`;
}
// 应用主题样式
if (StorageUtil.getReaderConfig("themeColor") &&
StorageUtil.getReaderConfig("themeColor") !== "default") {
require("./assets/styles/" +
StorageUtil.getReaderConfig("themeColor") + ".css");
}
高亮和标注系统
系统支持多种颜色的高亮和划线标注功能,每种颜色都有对应的CSS类名:
export const classes = [
"color-0", // 黄色高亮
"color-1", // 黄色高亮(亮色)
"color-2", // 绿色高亮
"color-3", // 蓝色高亮
"line-0", // 红色下划线
"line-1", // 深蓝色下划线
"line-2", // 蓝色下划线
"line-3", // 绿色下划线
];
export const colors = ["#fac106", "#ebe702", "#0be603", "#0493e6"];
export const lines = ["#FF0000", "#000080", "#0000FF", "#2EFF2E"];
主题管理功能
Koodo Reader 提供了完整的主题管理功能,包括主题的添加、删除和排序:
static setThemes(themeName: string) {
let themeArr = localStorage.getItem("themeColors") !== "{}" &&
localStorage.getItem("themeColors")
? JSON.parse(localStorage.getItem("themeColors") || "")
: [];
const index = themeArr.indexOf(themeName);
if (index > -1) {
themeArr.splice(index, 1);
themeArr.unshift(themeName);
} else {
themeArr.unshift(themeName);
}
localStorage.setItem("themeColors", JSON.stringify(themeArr));
}
响应式设计
系统能够自动检测操作系统主题设置,实现无缝的明暗主题切换:
// 检测系统颜色主题
const isNight = ipcRenderer.sendSync("system-color") ||
window.matchMedia("(prefers-color-scheme: dark)").matches;
// 设置应用皮肤
if (!StorageUtil.getReaderConfig("appSkin")) {
StorageUtil.setReaderConfig("appSkin", "system");
}
// 应用主题设置
if (StorageUtil.getReaderConfig("appSkin") === "night" ||
(StorageUtil.getReaderConfig("appSkin") === "system" &&
StorageUtil.getReaderConfig("isOSNight") === "yes")) {
// 应用夜间模式
}
字体管理系统
Koodo Reader 支持系统字体检测和自定义字体设置:
// 获取系统字体列表
const fontList = window.require("font-list");
fontList.getFonts({ disableQuoting: true }).then((result) => {
dropdownList[0].option.push("Built-in font");
});
// 应用自定义字体
if (StorageUtil.getReaderConfig("systemFont")) {
document.documentElement.setAttribute(
"style",
"font-family:" + StorageUtil.getReaderConfig("systemFont") + "!important"
);
}
通过这套完整的自定义阅读界面与主题系统,Koodo Reader 为用户提供了高度个性化的阅读体验,无论是白天还是夜晚,纸质书还是电子屏,都能找到最适合的阅读配置。
文本转语音(TTS)功能实现
Koodo Reader的文本转语音功能为用户提供了沉浸式的听书体验,通过先进的语音合成技术将电子书内容转换为自然流畅的语音输出。该功能支持多种语音引擎和自定义配置,实现了跨平台的语音朗读解决方案。
架构设计
Koodo Reader的TTS系统采用分层架构设计,包含以下几个核心组件:
classDiagram
class TextToSpeechComponent {
+componentDidMount()
+handleChangeAudio()
+handleStartSpeech()
+handleAudio()
+handleRead()
+handleSystemRead()
}
class TTSUtil {
+readAloud()
+cacheAudio()
+pauseAudio()
+getAudioPaths()
+getVoiceList()
}
class PluginList {
+getAllVoices()
+getPluginById()
}
class ElectronMain {
+generate-tts IPC
+clear-tts IPC
}
TextToSpeechComponent --> TTSUtil
TTSUtil --> PluginList
TTSUtil --> ElectronMain
核心功能实现
语音合成引擎集成
Koodo Reader支持两种类型的语音合成引擎:
- 系统原生TTS引擎:基于Web Speech API的实现
- 插件化自定义引擎:通过插件系统扩展第三方语音服务
// 系统语音检测与初始化
async componentDidMount() {
if ("speechSynthesis" in window) {
this.setState({ isSupported: true });
}
const setSpeech = () => {
return new Promise((resolve, reject) => {
let synth = window.speechSynthesis;
let id = setInterval(() => {
if (synth.getVoices().length !== 0) {
resolve(synth.getVoices());
clearInterval(id);
}
}, 10);
});
};
this.nativeVoices = await setSpeech();
}
语音播放控制
TTS组件实现了精细的播放控制机制,包括开始、暂停、继续和停止功能:
handleChangeAudio = () => {
if (this.state.isAudioOn) {
window.speechSynthesis.cancel();
TTSUtil.pauseAudio();
this.setState({ isAudioOn: false });
} else {
this.handleStartSpeech();
}
};
文本处理与分段朗读
系统能够智能处理电子书文本,实现分段朗读和高亮同步:
handleGetText = async () => {
this.nodeList = this.props.htmlBook.rendition
.audioText()
.filter((item: string) => item && item.trim());
if (this.nodeList.length === 0) {
await this.props.htmlBook.rendition.next();
this.nodeList = await this.handleGetText();
}
return this.nodeList;
};
插件系统集成
Koodo Reader通过插件系统支持多种语音引擎,提供了灵活的扩展能力:
插件管理
class PluginList {
static getAllVoices() {
let pluginList = JSON.parse(localStorage.getItem("pluginList") || "[]");
let voiceList: any[] = [];
for (const plugin of pluginList.filter((item) => item.type === "voice")) {
voiceList.push(...(plugin.voiceList as any[]));
}
return voiceList;
}
}
语音插件模型
class Plugin {
identifier: string;
type: string;
displayName: string;
icon: string;
version: string;
config: object;
langList: object | any[];
voiceList: object | any[];
script: string;
constructor(identifier: string, type: string, displayName: string,
icon: string, version: string, config: object,
langList: any, voiceList: any, script: string) {
// 初始化逻辑
}
}
音频缓存与播放
系统采用高效的音频缓存机制,确保流畅的朗读体验:
static async cacheAudio(nodeList: string[], voiceIndex: number, speed: number = 0) {
let voiceList = PluginList.getAllVoices();
if (voiceIndex >= voiceList.length) voiceIndex = 0;
let voice = voiceList[voiceIndex];
if (!voice || !voice.plugin) return;
let plugin: Plugin = PluginList.getPluginById(voice.plugin);
for (let index = 0; index < nodeList.length; index++) {
const nodeText = nodeList[index];
let audioPath = await window.require("electron").ipcRenderer.invoke(
"generate-tts", {
text: nodeText.replace(/\s\s/g, "").replace(/\r/g, ""),
speed,
plugin: plugin,
voiceName: voice.name,
}
);
this.audioPaths.push(audioPath);
}
}
主进程音频生成
Electron主进程负责实际的音频文件生成:
ipcMain.handle("generate-tts", async (event, config) => {
let { text, speed, voiceName, plugin } = config;
const sparkMd5 = require('spark-md5');
const hash = sparkMd5.hash(plugin.script);
// 安全验证
if (hash !== "fd4638b1c069404933607227a60aed62") return "";
let voiceFunc = plugin.script;
eval(voiceFunc); // 执行插件脚本
return global.getAudioPath(text, speed, dirPath, {
voiceName: voiceName,
voiceFormat: "webm-24khz-16bit-mono-opus"
});
});
语音参数配置
系统支持丰富的语音参数调节,包括语速、音色选择等:
| 参数类型 | 可选值范围 | 默认值 | 说明 |
|---|---|---|---|
| 语速 | 0.1 - 5.0 | 1.0 | 朗读速度倍数 |
| 语音类型 | 系统语音+插件语音 | 系统默认 | 支持多种音色 |
| 音频格式 | webm-24khz-16bit-mono-opus | webm | 音频输出格式 |
// 语速配置处理
handleSelect = () => {
document.querySelector("#text-speech-speed")!.children[
speedList.option.indexOf(
StorageUtil.getReaderConfig("voiceSpeed") || "1"
)
]?.setAttribute("selected", "selected");
};
实时高亮同步
朗读过程中实现文本高亮同步,提升用户体验:
async handleSystemRead(index) {
let currentText = this.nodeList[index];
let style = "background: #f3a6a68c";
this.props.htmlBook.rendition.highlightNode(currentText, style);
let res = await this.handleSystemSpeech(
index,
parseInt(StorageUtil.getReaderConfig("voiceIndex")) || 0,
parseFloat(StorageUtil.getReaderConfig("voiceSpeed")) || 1
);
// 处理朗读结果
}
错误处理与恢复机制
系统具备完善的错误处理和恢复机制:
handleSpeech = async (index: number, voiceIndex: number, speed: number) => {
return new Promise<string>(async (resolve, reject) => {
let res = await TTSUtil.readAloud(index);
if (res === "loaderror") {
resolve("start"); // 错误恢复
} else {
let player = TTSUtil.getPlayer();
player.on("end", async () => {
if (!(this.state.isAudioOn && this.props.isReading)) {
resolve("end");
}
resolve("start");
});
}
});
};
跨平台兼容性
TTS功能在不同平台上的表现:
| 平台 | 原生TTS支持 | 插件支持 | 性能表现 |
|---|---|---|---|
| Windows | ✓ | ✓ | 优秀 |
| macOS | ✓ | ✓ | 优秀 |
| Linux | ✓ | ✓ | 良好 |
| Web | ✓ | ✗ | 受限 |
性能优化策略
- 音频预缓存:提前生成并缓存音频片段
- 内存管理:及时清理已播放的音频资源
- 网络优化:支持离线语音插件
- 电池优化:智能功耗控制
Koodo Reader的文本转语音功能通过精心设计的架构和实现,为用户提供了高质量、可定制的听书体验,充分体现了现代电子书阅读器的智能化发展方向。
书签、笔记和高亮功能设计
Koodo Reader作为一款现代化的电子书阅读器,其书签、笔记和高亮功能的设计体现了对深度阅读体验的精心考量。这些功能不仅帮助读者更好地组织和管理阅读内容,还提供了丰富的交互方式来增强阅读理解和知识积累。
数据模型架构设计
Koodo Reader采用了清晰的数据模型分离策略,将书签、笔记和高亮功能分别建模为独立的实体类:
// 书签模型
class Bookmark {
key: string; // 唯一标识符
bookKey: string; // 所属书籍标识
cfi: string; // 阅读位置CFI标识
label: string; // 书签标签
percentage: number; // 阅读进度百分比
chapter: string; // 所在章节
}
// 笔记模型
class Note {
key: string; // 唯一标识符
bookKey: string; // 所属书籍标识
date: { year: number; month: number; day: number }; // 创建日期
chapter: string; // 所在章节
chapterIndex: number; // 章节索引
text: string; // 原文内容
cfi: string; // 位置CFI标识
range: string; // Rangy.js序列化范围
notes: string; //
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin07
compass-metrics-modelMetrics model project for the OSS CompassPython00