diff --git a/blocksuite/playground/examples/renderer/canvas.worker.ts b/blocksuite/playground/examples/renderer/canvas.worker.ts index ab92f84fd..e89f8f978 100644 --- a/blocksuite/playground/examples/renderer/canvas.worker.ts +++ b/blocksuite/playground/examples/renderer/canvas.worker.ts @@ -42,6 +42,9 @@ class CanvasWorkerManager { const { canvas, ctx } = this; if (!canvas || !ctx) return; + // Track rendered positions to avoid duplicate rendering across all paragraphs and sentences + const renderedPositions = new Set(); + paragraphs.forEach(paragraph => { const scale = paragraph.scale ?? 1; const fontSize = 15 * scale; @@ -53,14 +56,16 @@ class CanvasWorkerManager { sentence.rects.forEach(textRect => { const x = textRect.rect.left - hostRect.left; const y = textRect.rect.top - hostRect.top; - ctx.strokeRect(x, y, textRect.rect.width, textRect.rect.height); - }); - ctx.fillStyle = 'black'; - sentence.rects.forEach(textRect => { - const x = textRect.rect.left - hostRect.left; - const y = textRect.rect.top - hostRect.top; + const posKey = `${x},${y}`; + // Only render if we haven't rendered at this position before + if (renderedPositions.has(posKey)) return; + + ctx.strokeRect(x, y, textRect.rect.width, textRect.rect.height); + ctx.fillStyle = 'black'; ctx.fillText(textRect.text, x, y + baselineY); + + renderedPositions.add(posKey); }); }); }); diff --git a/blocksuite/playground/examples/renderer/text-utils.ts b/blocksuite/playground/examples/renderer/text-utils.ts index f3c797493..a13958762 100644 --- a/blocksuite/playground/examples/renderer/text-utils.ts +++ b/blocksuite/playground/examples/renderer/text-utils.ts @@ -89,7 +89,6 @@ export function getSentenceRects( element: Element, sentence: string ): TextRect[] { - const range = document.createRange(); const textNode = Array.from(element.childNodes).find( node => node.nodeType === Node.TEXT_NODE ); @@ -97,13 +96,20 @@ export function getSentenceRects( if (!textNode) return []; const text = textNode.textContent || ''; - const startIndex = text.indexOf(sentence); - if (startIndex === -1) return []; + let rects: TextRect[] = []; + let startIndex = 0; - range.setStart(textNode, startIndex); - range.setEnd(textNode, startIndex + sentence.length); + // Find all occurrences of the sentence + while ((startIndex = text.indexOf(sentence, startIndex)) !== -1) { + const range = document.createRange(); + range.setStart(textNode, startIndex); + range.setEnd(textNode, startIndex + sentence.length); - return getRangeRects(range, sentence); + rects = rects.concat(getRangeRects(range, sentence)); + startIndex += sentence.length; // Move to next potential occurrence + } + + return rects; } export function segmentSentences(text: string): string[] {