Commit 67b09ef7 authored by liujiangnan's avatar liujiangnan

feat: 优化逐字逻辑体验

parent 53723d82
...@@ -415,18 +415,74 @@ function initializeApp(data) { ...@@ -415,18 +415,74 @@ function initializeApp(data) {
const allRects = this.currentPageRects; const allRects = this.currentPageRects;
const allWords = this.currentPageWords; const allWords = this.currentPageWords;
// 遍历所有矩形框,检查时间 // 预构建句子时间窗映射(按组和原始页索引)
const sentenceWindowByGroup = {};
allRects.forEach(rect => { allRects.forEach(rect => {
if (rect._start != null && rect._end != null && currentTime >= rect._start && currentTime <= rect._end) { const key = `${rect._originalPageIndex}:${rect._groupIndex}`;
if (!sentenceWindowByGroup[key]) {
let start = rect._start;
let end = rect._end;
// 若句子时间缺失,回退到所在页或当前页窗口
if (start == null || end == null) {
const page = this.currentPages[rect._pageIndex];
if (page) {
if (start == null) start = (page.start != null ? page.start : this.currentPageStartTime);
if (end == null) end = (page.end != null ? page.end : this.currentPageEndTime);
} else {
if (start == null) start = this.currentPageStartTime;
if (end == null) end = this.currentPageEndTime;
}
}
sentenceWindowByGroup[key] = { start, end };
}
});
// 遍历所有矩形框,检查时间(句子窗口)
allRects.forEach(rect => {
const rectStart = (rect._start != null ? rect._start : this.currentPageStartTime);
const rectEnd = (rect._end != null ? rect._end : this.currentPageEndTime);
if (currentTime >= rectStart && currentTime <= rectEnd) {
newRects.push(rect); newRects.push(rect);
} }
}); });
// 遍历所有单词,检查时间 // 遍历所有单词,要求在“句子窗口”内;一旦点亮,保持到句子结束。
// 健壮性:若某个短词错过点亮,但后续词已点亮,则回补此前所有词。
const wordsByGroup = {};
allWords.forEach(word => { allWords.forEach(word => {
// 如果当前时间已经过了这个单词的开始时间,就保持高亮直到切换页面 if (!word) return;
if (word.start != null && currentTime >= word.start) { const key = `${word._originalPageIndex}:${word._groupIndex}`;
newWords.push(word); (wordsByGroup[key] = wordsByGroup[key] || []).push(word);
});
Object.keys(wordsByGroup).forEach(key => {
const groupWords = wordsByGroup[key];
const win = sentenceWindowByGroup[key];
const sentenceStart = win ? win.start : this.currentPageStartTime;
const sentenceEnd = win ? win.end : this.currentPageEndTime;
// 仅在句子窗口内处理该组
if (currentTime < sentenceStart || currentTime > sentenceEnd) return;
// 按 _groupsIndex 升序,确保回补逻辑按顺序进行
groupWords.sort((a, b) => (a._groupsIndex || 0) - (b._groupsIndex || 0));
// 找到当前时间已经“开始”的最远索引(仅根据 start 判断)
let progressIndex = -1;
for (let i = 0; i < groupWords.length; i++) {
const w = groupWords[i];
if (w.start != null && currentTime >= w.start) {
progressIndex = i;
}
}
// 若已有任一后续词点亮,则回补至该索引之前的所有词(包含无 start 的)
if (progressIndex >= 0) {
for (let j = 0; j <= progressIndex; j++) {
newWords.push(groupWords[j]);
}
} }
}); });
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment