偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

圖形編輯器:歷史記錄設(shè)計(jì)

開(kāi)發(fā) 前端
要記錄圖形編輯器的歷史記錄,支持撤銷重做功能,需要兩個(gè)棧:撤銷(undo)棧和重做(redo)棧。

大家好,我是前端西瓜哥。今天講一下圖形編輯器如何實(shí)現(xiàn)歷史記錄,做到撤銷重做。

其實(shí)就是版本號(hào)的更替。每個(gè)版本保存一個(gè)狀態(tài)。

數(shù)據(jù)結(jié)構(gòu)

要記錄圖形編輯器的歷史記錄,支持撤銷重做功能,需要兩個(gè)棧:撤銷(undo)棧和重做(redo)棧。

每當(dāng)用戶進(jìn)行一個(gè)操作(比如移動(dòng)一個(gè)圖形),就會(huì)產(chǎn)生一個(gè)新的版本,將這個(gè)操作產(chǎn)生的狀態(tài)保持加入到 undo 棧頂,此外 redo 棧會(huì)清空。因?yàn)橛脩艨赡艹蜂N了幾次然后產(chǎn)生了新的操作,無(wú)法重做它們了。

當(dāng)用戶撤銷,undo 棧出棧,并放到 redo 棧,然后使用 undo 棧頂?shù)臓顟B(tài)。當(dāng)用戶重做時(shí),redo 棧出棧,再放到 undo 棧上,并應(yīng)用 undo 棧頂?shù)臓顟B(tài)。

原理大概這樣。

瀏覽器的回退前進(jìn)的表現(xiàn)其實(shí)就是一個(gè)很常見(jiàn)的例子。

數(shù)據(jù)結(jié)構(gòu)還有另一種方案:雙向鏈表加兩個(gè)指針,一個(gè)指針指向當(dāng)前版本狀態(tài),另一個(gè)指針指向 redo 最后一次可執(zhí)行到達(dá)的狀態(tài)。

然后是如果要支持協(xié)同的場(chǎng)景,你的撤回不會(huì)回到之前的版本,而是將之前的版本的狀態(tài)拿出來(lái)作為一個(gè)新的版本。

協(xié)同中你也不能撤回別人的操作,只能撤回自己的,并且要用協(xié)同算法處理和其他協(xié)同者的沖突邏輯。

要保存哪些狀態(tài)

那么我們的狀態(tài)要保存哪些狀態(tài)呢?

  1. 圖形樹(shù)數(shù)據(jù)
  2. 圖形樹(shù)需要的引用
  3. 一些設(shè)置

圖形樹(shù)是必要的,我們需要用它渲染畫(huà)布內(nèi)容。此外還有游離在圖形樹(shù)之外的被用到的對(duì)象,比如圖層、被多次引用的圖形。你可以也把它們也放到圖形樹(shù)里面去。

最后是一些需要共享的設(shè)置,比如表格的行高、篩選條件等。

像是顏色主題、國(guó)際化語(yǔ)言設(shè)置則不需要?dú)v史記錄,它是用戶自己選擇的個(gè)性化定制。

我們看具體的幾種實(shí)現(xiàn)。

全量快照

每次操作得到的新?tīng)顟B(tài),完全拷貝一份保存起來(lái)。

因?yàn)閷?duì)象如果只是淺拷貝,其中的引用對(duì)象可能會(huì)被意外地修改,通常我們會(huì)選擇 序列化成字符串 保存,即JSON.stringify。撤銷重做的時(shí)候再解析出來(lái)作為當(dāng)前狀態(tài)。

優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單。巨大的優(yōu)點(diǎn)。

缺點(diǎn)是當(dāng)狀態(tài)很大的時(shí)候,每次生成快照都會(huì)比較耗時(shí),且操作很多產(chǎn)生很多版本時(shí),需要大量的內(nèi)存空間保存這些完整狀態(tài)。

如果畫(huà)布上有一萬(wàn)個(gè)獨(dú)立的實(shí)體,就意味著每進(jìn)行一次操作,就要將這個(gè)一萬(wàn)個(gè)實(shí)體深拷貝一份。100 次就是 100w,很恐怖。

僅推薦簡(jiǎn)單的圖形編輯器使用,或者做 demo 用。

補(bǔ)丁(patch)

全量快照讓編輯器的上限很低,不是最優(yōu)解。

一種更好的解法,是 打補(bǔ)?。╬atch)。

基于上一個(gè)版本 1,打一個(gè)補(bǔ)丁,變成下一個(gè)版本 2。同時(shí)我們記錄一個(gè)反向的補(bǔ)丁,撤回的時(shí)候能通過(guò)它從版本 2 回到版本 1。

這個(gè)方案對(duì)應(yīng)了設(shè)計(jì)模式的 命令模式,我們構(gòu)建 Command 類,這個(gè)類有 execute、redo、undo 方法,這些方法會(huì)對(duì)傳入的舊的狀態(tài)對(duì)象打補(bǔ)丁,得到一個(gè)新的狀態(tài)。

比如添加矩形命令,execute 和 redo 時(shí)我們會(huì)往圖形樹(shù)的末尾加一個(gè)矩形對(duì)象,undo 就是將這個(gè)矩形從圖形樹(shù)中移除。undo 棧和 redo 棧此時(shí)記錄的就是一個(gè)個(gè) command 對(duì)象了。

圖片

純純用樸實(shí)無(wú)華的命令模式去實(shí)現(xiàn),還是有點(diǎn)坑的。因?yàn)橐獙?shí)現(xiàn)的命令太多了,比如添加圖形、修改圖形屬性、刪除圖形、對(duì)幾個(gè)圖形做右對(duì)齊等,這些都要自己一個(gè)個(gè)實(shí)現(xiàn) redo 和 undo。復(fù)雜一點(diǎn)就要抓瞎,建議找一些輪子。比如 immer、y.js。

使用補(bǔ)丁方案還有一個(gè)好處,就是方便實(shí)現(xiàn) “動(dòng)作” 功能。(當(dāng)然這不是一個(gè)優(yōu)先級(jí)很高的功能)

比如我們想要給一個(gè)圖形先順時(shí)針旋轉(zhuǎn) 45 度,然后向右移動(dòng) 10 個(gè)單位,我們希望記錄這兩個(gè)操作,給其他圖形也應(yīng)用這些操作。

快照的方式就不好搞,或許我們可以對(duì)比新舊狀態(tài)找不同推斷出行為,但不好搞。因?yàn)閷傩缘淖兓赡軄?lái)自不同的操作,比如移動(dòng),可以通過(guò)移動(dòng)工具相對(duì)位移產(chǎn)生,也可能直接屬性面板改 x 值,也可能是通過(guò)對(duì)齊操作產(chǎn)生的。

patch 就很適合。

什么時(shí)候保存狀態(tài)

我們需要確認(rèn)一個(gè)操作完成的時(shí)刻,將它加入到歷史記錄中。

我們操作圖形,會(huì)產(chǎn)生一些 中間狀態(tài)。比如移動(dòng)一個(gè)圖形,拖拽的過(guò)程中不生產(chǎn)一個(gè)歷史版本,直到拖拽結(jié)束才記錄。

一種方式是:操作圖形的替身,操作結(jié)束后才更新真正的狀態(tài)。

一些編輯器,比如 Adobe Illustrator、AutoCAD,我們?cè)诓僮鲌D形的時(shí)候,會(huì)看到一個(gè)臨時(shí)的替身,就是將被選中圖形的輪廓線或拷貝做鼠標(biāo)的跟隨,鼠標(biāo)釋放后才真正修改圖形屬性。

還比如顏色的修改,在拾色器中挑選顏色時(shí)不會(huì)立即修改圖形,在點(diǎn)擊確認(rèn)才真正修改圖形顯示在畫(huà)布上。

圖片

另一種方式是:直接操作真正的狀態(tài),在操作結(jié)束的時(shí)候,記錄這個(gè)時(shí)刻的狀態(tài)。

圖片

第一種方式的好處是,狀態(tài)沒(méi)有中間狀態(tài),替身操作完,計(jì)算出新?tīng)顟B(tài)應(yīng)用到真正的狀態(tài)上就好了。

第二種方式就要額外在操作開(kāi)始時(shí),保存原始狀態(tài)的快照,因?yàn)橹笪覀儠?huì)產(chǎn)生中間狀態(tài),然后在操作結(jié)束后計(jì)算 patch。

但第二種方式用戶體驗(yàn)會(huì)更好些,用戶能實(shí)時(shí)看到一個(gè)圖形的變化,判斷是不是自己需要的效果,而不是看到一個(gè) “通往未來(lái)的幻影”。

責(zé)任編輯:姜華 來(lái)源: 前端西瓜哥
相關(guān)推薦

2024-01-22 10:01:41

Git 提交快照

2009-08-20 16:25:05

Linux系統(tǒng)歷史記錄linux

2011-10-09 14:57:35

2021-04-27 15:38:10

GoogleChrome歷史記錄

2013-12-05 17:37:57

Windows 8文件歷史記錄

2022-01-25 11:33:14

數(shù)據(jù)泄露網(wǎng)絡(luò)攻擊

2013-01-21 14:37:05

Windows 8歷史記錄

2009-07-07 15:49:04

root命令歷史記錄安全性 

2021-01-06 18:10:22

ShellLoki系統(tǒng)運(yùn)維

2021-12-15 23:33:33

Windows 11Windows微軟

2017-03-27 16:15:42

ChromeVivaldi瀏覽器

2016-01-27 11:24:20

Windows 10紅石鏡像

2016-01-26 15:27:16

Windows 10歷史記錄備份

2023-08-01 09:30:12

SQL Server數(shù)據(jù)庫(kù)

2021-01-20 09:29:09

QQ瀏覽器App

2023-10-19 10:12:34

圖形編輯器開(kāi)發(fā)縮放圖形

2019-10-14 16:16:49

BashLinux命令

2023-06-02 10:41:50

2022-04-29 16:47:57

AI騰訊

2020-06-01 18:20:41

Git
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)