從零開始,開發一個 Web Office 套件(9):拖動滑鼠選中文字 Edge Case

趙康發表於2022-03-15

這是一個系列部落格,最終目的是要做一個基於 HTML Canvas 的、類似於微軟 Office 的 Web Office 套件(包括:文件、表格、幻燈片……等等)。
部落格園:《從零開始, 開發一個 Web Office 套件》系列部落格目錄
富文字編輯器 Github repo 地址:https://github.com/zhaokang555/canvas-text-editor

上一節我們初步完成了拖動選中文字的feature,不過還遺留了一些 edge case。這篇文章我們來處理它們。

2. 富文字編輯器 (MVP)

2.21 拖動滑鼠選中文字

2.21.3 Fix: Should hide blinking cursor after selecting text

細心地讀者會發現:當我們選擇完文字之後,應該隱藏掉游標,結果卻沒有。如下圖所示:

現在,我們來修復它:

  • 第一步,修改Char:在完成點選字元之後,不要直接呼叫blinkingCursor.show()來展示游標, 改為呼叫blinkingCursor.afterClick()。後續的邏輯在blinkingCursor內部處理,由它自己判斷自己是否應該顯示。
  • 第二步,修改BlinkingCursor:實現afterClick方法,並在其中進行判斷:
    • 如果選中了文字,就隱藏游標
    • 如果沒有選中文字,就顯示游標
  • 第三步,修改Store,實現hasSelectText方法

效果:

2.21.4 Fix: Should select text from back to front

當我們從後向前(從右向左、從下向上)選擇文字時,會發現無法選中。如下圖所示:

這一小節,我們來修復這個問題。首先,修改Store:

  • 刪除欄位mouse.select.beginChar, mouse.select.endChar
  • 新增欄位:mousedownChar(滑鼠按下時處於哪個字元), mouseupChar(滑鼠彈起時處於哪個字元)
  • 新增欄位:isMousedownLeftHalf(滑鼠按下時處於字元哪半邊), isMouseupLeftHalf(滑鼠彈起時處於字元哪半邊)
  • 修改finishSelect(): 根據上面新新增的四個欄位,計算出正確的beginIndexendIndex
  • 修改clearSelect()

對應的,修改Char,給上面新新增的四個欄位賦值:

效果:

2.21.5 Fix: 當從頁面空白處按下/彈起滑鼠時,應該正確地選中文字

我們先看下目前的問題。

當從頁面空白處按下滑鼠時,選擇的文字範圍不正確:

當從頁面空白處彈起滑鼠時,選擇的文字範圍不正確:

然後,我們來解決這個問題:

  • 第一步,重構:從空白區域(Editor.blankSpace)的click處理邏輯中,抽象出mapPositionInBlankSpaceToChar,給後續處理空白區域mousedown和mouseup的邏輯時使用。

  • 第二步:新建一個類MouseDownUpClickZone,用來表示支援三種事件(click/mousedown/mouseup)的區域,方便以後複用;並將blankSpaceClickableZone重構為MouseDownUpClickZone

  • 第三步,重構:順手將HalfChar重構為MouseDownUpClickZone。同時,刪除HalfChar類,它的歷史使命已經結束了。

效果:

(未完待續)

相關文章