iT邦幫忙

0

手刻web texteditor如何計算cursor位置(angular)

問題

今天我在一個這樣的結構裡面放文字

<div><span>{{rederedContent}}<span></div>
    font-size: 16px;
    font-family: monospace

各種英文數字中文字最後的大小都不是16px,我也試過在view check之後直接紀錄真實的Cursor位置(viewcheck之後取得指定line來計算),但view更新的頻率感人,字數一多看起來不像是複製貼上了。

目前的想法

我想盡量避免每個char都用一個span來包的情況,比較希望可以作出下面的這種感覺:

interface Line {
    content: string, // 該行的內容ex: abcAbc123我
    colOffset: Array<number>, // 正在編輯 n column 時,cursor的座標 
    colCharPx: Array<number>  // 佔據第 n cloumn 的字元在view上的實際大小
}

目前上面的東西都算得出來,但就卡在view的更新頻率不夠,所以我猜大概是我找的方向錯了

目前想法是,有沒有方法在render前得知或計算出某個char(string)渲染後的真實大小?
如果說inputElement本身有辦法作到,那應該有辦法獲取相關的資訊才對(?

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

2
fillano
iT邦超人 1 級 ‧ 2020-08-23 16:34:55
最佳解答

參考:
https://www.w3.org/TR/2dcontext2/#dom-context-2d-measuretext

Canvas 2D Context裡面所提供計算文字渲染大小的測量方法,回傳是一個結構:
https://www.w3.org/TR/2dcontext2/#textmetrics

各欄位定義可以參考這個圖,比較直覺:
https://www.w3.org/TR/2dcontext2/#dom-context-2d-textbaseline

在使用前,要指定好style,不然算出來一定跟你要的不一樣:
https://www.w3.org/TR/2dcontext2/#text-styles

你可以嘗試看看,我沒印象html element裡面有可以這樣測量的方式,所以透過Canvas來做是一個可能的方法。

看更多先前的回應...收起先前的回應...
jokie7585 iT邦新手 5 級 ‧ 2020-08-23 18:29:06 檢舉

感謝大大提供的資料
所以確實是沒有辦法取得innerHtml渲染bound之類的資訊喽?

jokie7585 iT邦新手 5 級 ‧ 2020-08-23 18:31:38 檢舉

也就是在 DOM改變 => reReder 之間,我們大概是無法透過js取得任何有關某element渲染後的資訊的?

jokie7585 iT邦新手 5 級 ‧ 2020-08-23 19:19:31 檢舉

另外再問一下,如果我執行很多console.log會影響到event-loop或dom/render的效率嗎?

fillano iT邦超人 1 級 ‧ 2020-08-23 23:12:21 檢舉

也不是取不到box-model相關的資訊,用canvas只是可以事先算。(但是算多行、雙向對齊等恐怕會比較麻煩)

box-model相關資訊,例如:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model

console.log可能會有影響,在node.js環境影響還蠻大的(轉檔之類)。不過網頁上很少持續的運算操作,可能不會有感覺,建議自己測試一下會比較清楚。如果真的有會影響到操作順暢度的運算,可以用web worker來做。

jokie7585 iT邦新手 5 級 ‧ 2020-08-24 07:29:25 檢舉

了解了 非常感謝fillano /images/emoticon/emoticon01.gif

我要發表回答

立即登入回答