# HW5 使用命令物件 (Command Object) 撤銷 請訪問[此連結](https://classroom.github.com/a/JJ3jryix)以取得 HW5 起始程式碼,並遵照 `readme.md` 執行檔案,若有遇到任何問題請聯繫助教。 請在 **<font color="#f00">2023 年 05 月 10 日下午 23:59 (UTC+8)</font>** 之前將此文件連同程式碼提交至所開設的 repo。我們將以截止時間前最後一次提交的內容作為批改項目。 ## 作業概述 在此作業中,請使用使用線性取消模型 (linear undo model) 將撤銷功能添加到作業三的圖形編輯器中,該模型使用命令物件模式 (Command Object pattern) 實現。我們在 React 中創建了一個編輯器的參考實作,**您需要使用它**。 請注意,此版本刪除了 Canvas 圖層和全部刪除按鈕(並且不包括線條繪製),因為我們認為這些對學習撤銷沒有幫助。 與之前的作業一樣,你**可以**使用某些函式庫,包含React, [Create-React-App](https://create-react-app.dev/docs/getting-started/), [ReactRouter](https://reactrouter.com/en/6.9.0), [ReactStrap](https://www.npmjs.com/package/reactstrap), [React Context API](https://legacy.reactjs.org/docs/context.html)(這是一個較新的 API,正在成為跨組件傳遞資料的流行方式)。我們在按鈕上使用的圖標來自 [react-icons](https://react-icons.github.io/react-icons/),如果你預計實作右方額外命令物件列表的加分作業,那麼 [react-scroll-to-bottom](https://www.npmjs.com/package/react-scroll-to-bottom) 可在此派上用場。 然而,你**不可以**使用函式庫實作命令對像模式,如果想使用非上面提及之函式庫,請寄信詢問助教。 此作業的使用者界面與作業三基本相同,差異在於新增了撤消和重做按鈕,並刪除了 Canvas 圖層、全部刪除功能與線條繪製。 ## 可用資源 Michael Liu 和 Clara Cook (HCII 課程助教) 已實作作業三內容,請點選[此連結](https://classroom.github.com/a/JJ3jryix)以取得該內容的起始程式碼。**請注意:你必須修改起始程式碼的基本實作,而不僅僅是新增文件,具體來說,請在創建、修改和刪除物件的所有位置編輯程式碼,以便使用命令物件來執行這些操作,並使物件可被撤銷。** 我們已針對實現命令物件的方法創建一組JavaScript 規範文件,以及有關更改填充顏色的命令物件,但尚不能真正作用的草稿,請應該使用這些來構建命令物件和線性撤消。 起始程式碼包含以下文件: * `hw5-undo-using-command-objects-YOURID/` - 此資料夾包含所有使用 React 實作圖形編輯器的相關文件,你必須基於這些程式碼,並新增撤銷處理功能。此資料夾還包含: * `CommandObject.js` 和 ``ChangeFillColorCommandObject.js`` - 這些文件位於子目錄 hw5-undo-using-command-objects-YOURID/src/shared/commandObjects/,提供與實作命令物件相關的結構和範例。 此外,請瀏覽以下圖片和影片,以了解具體規範: * [HW5-example.mp4](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW5/HW5-example.mp4) - 一段說明作業五應有的模樣與事件的影片 * [HW5-base.png](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW5/HW5-base.png) - 從基本版本開始的界面示意圖 * [HW5-command-list.png](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW5/HW5-command-list.png) - 執行幾項操作,並撤銷三個命令後的界面示意圖 ## 詳細要求 請實作以下要求,並參考前段所附之影片與圖片,以獲得滿分。如果作業敘述上有些模糊,或是你的實作可能會偏離定義行為,請以信件或 NTU COOL 詢問助教。 * 所有的操作都可以如同尋常程式一般是**可撤銷**的,類似於 PowerPoint 撤銷的運作機制。詳細資訊請參考上章節中的影片。當撤銷執行後,需恢復繪圖並選取受影響物件。 * 使用者必須能**連續執行多個撤銷操作**,直到回到初始狀態(線性撤銷模型)。 * 在撤銷執行後,使用者可使用**重做按鍵**來取消撤銷行為,並讓繪圖回復到撤銷發生前的狀態。可執行的重做次數應和撤銷次數相同。 * 如果使用者在執行一個以上的撤銷操作後,**執行並非撤銷或重做的其他操**作,那麼**之前撤銷的操作將不可被重做**(這是線性撤銷模型的標準方式),且新操作應被儲存在撤銷堆疊 (stack)中。 * 請針對每一個操作(創建、刪除、移動物件、更改填充顏色、更改線條顏色、更改線條寬度),**定義從 `CommandObject` 擴展 (extend) 的類別 (Class)** * 當撤銷跟重做按鈕不可被使用時,他們應該是灰色的 * 當沒有任何先前操作時,撤銷按鈕應該變灰 * 當沒有任何已撤銷操作可重做時,重做按鈕應該變灰 * 可撤銷的操作包含: * **創建(圖形繪製)**: * 撤銷後會使該物件消失,且**不選取**任何物件。(注意:此部分與 PowerPoint 撤銷後會選取先前物件的實作不同) * 重做創建操作後,在任何情形中都將**自動選取**重新建立的物件。 * **更改填充顏色或邊框顏色**: * 執行撤銷後將使顏色恢復到更改前狀態。 * 如果使用者在選取物件後多次更改顏色,這些動作都應該可單獨被撤銷。 * 受撤銷動作影響的物件應被選取,且操作面板上的顏色區塊應呈現當前值。 * **更改邊框寬度**: * 即使在拖曳操作面板上的邊框寬度滑塊 (slider) 時經過多個數值,在執行重做時僅需回復到拖曳滑塊前。舉例來說,如果拖曳滑塊前所選取物件邊框寬度為 3px,那麼按下滑鼠不放,並從 3px 拖曳到 10px 再回到 2px 後放開滑鼠,由於最終僅執行了將邊框由 3px 調整為 2px 的操作,因此點擊撤銷按鈕將使選取物件邊框變回 3px。 * 如果使用者連續兩次更改邊框寬度,那麼這兩次修改將可被單獨撤銷。 * 受撤銷操作影響的物件應被選取,且操作面板上的邊框寬度區塊應呈現當前值。 * **移動**: * 撤銷移動將使物件回復到先前的位置。如果更改邊框寬度一樣,只有按下滑鼠前與放開滑鼠後的物件位置,可被撤銷或重做按鈕影響。 * 受撤銷操作影響的物件應被選取。 * **刪除**: * 撤銷刪除將使物件重新出現並呈現被選取狀態,而重做將使物件再次消失並使圖層上沒有任何東西被選取。 * 注意:使用者可以在撤銷刪除 (A) 後手動選擇其他物件 (B) ,然後執行重做刪除。在這種情況下,重作刪除時仍需刪除原始物件 (A) * 注意:**單擊以選取其他物件是不可撤銷的行為**。也就是說,不可以為「選取物件」與「選取背景已取消所有選取」分配命令物件,也不可加入撤銷堆疊。 * 如果選取的物件因撤銷或重做而改變,則**操作面板的顏色、邊框寬度、邊框顏色...等值,應與改變後的選取物件符合**。 * 同樣的,**在更改繪圖模式(箭頭、矩形或圓形)後,或者在沒有選取任何物件時,更改當前顏色或邊框寬度,也同樣是不可撤銷的**,因此不可加入撤銷堆疊。然而,如果選取物件因為其他撤銷/重做行為發生變化,那麼操作面板狀態也會受影響。 * 由於**中止操作行為**(使用 ESC 停止當前操作)不改變任何狀態,因此**不應影響撤銷堆疊**。 * **在執行撤銷或重做後,請始終更改為選取模式**。舉例來說,如果使用者在選取模式下選取物件、改變顏色、將模式改為矩形模式,最後執行撤銷,在這種情形中,模式應該改回選取模式,以便選取顏色更改操作被撤銷的物件。即便撤銷創建或重做刪除時不需要選取任何物件,仍建議在任何情形中,皆在撤銷/重做後改為選取模式。 ## 加分項目 * **對所有與線條相關的操作提供撤銷/重做功能(最多在此作業中+5分)** * 我們不小心遺漏作業 3 中的線條繪製與編輯,由於本作業不需要,因此請註釋掉線條相關程式碼,或者也可以新增對線條繪製、刪除和編輯的撤銷/重做功能,以獲得高達 5 分的額外分數。 * **撤銷、重作鍵盤快捷鍵實現 (每個+1,最多在本作業中+2分)** * 將 ctrl+z (或 command+z)作為撤銷快捷鍵 * 將 ctrl+y (或 command+shift+z)作為重做快捷鍵 * **增加命令列表區塊(最多在此作業中+5分)** * 在繪圖區右側添加命令列表區塊,如同 [HW5-command-list.png](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW5/HW5-command-list.png) 和 [HW5-example.mp4](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW5/HW5-example.mp4)所顯示 * 若想獲取完整加分,請令該區塊顯示: * 當前操作 * 應該刪除「由於撤消之後進行新操作,而不可被重做」的操作 * 將未完成(撤銷且可被重做)的操作顯示為灰色 * **為所有編輯操作添加重複操作 (最多在此作業中+15分)** * 重做按鈕上的文字與 icon 應適時改變為重複 * 若當前有選取物件,則可將更改顏色與邊框寬度的操作,針對該物件進行重複套用。若無當前選取物件,則重複操作則不能被使用。 * 在執行重複時,必須重複創建命令物件 * 重複刪除應該刪除當前選取的物件 * 不能對移動操作進行重複 * 重複操作應出現在撤銷堆疊中,以便使用正常方式撤銷。如果你實作了繪圖區右側的命令列表區塊,則其應該有個合理的名字,例如 "repeat of change line border color to #ea3323" * 重複按鈕在不能使用時應該是灰色的。例如:移動操作。 * **添加四個輕推 (nudge) 移動操作 (每個方向 +2 分,最多在此作業中 +8 分)** * 在點擊鍵盤上、下、左、右鍵時,將所選物件朝該方向移動幾個像素。且其是可被撤銷的。 * 如同 PowerPoint 的實作一般,要取得所有加分,**請將多個同方向的輕推操作合併成一個可撤銷操作**。 * **使用直接逆模型 (direct inverse model) 添加對選擇性撤消和選擇性重複的支持(最多在此作業中 +15 分)** * 這個加分項目**需要你先實現上述的命令列表區塊加分項和重複加分項**,然後還要支持: * 通過點擊命令列表區塊中的命令來選擇它 * 在左側操作面板部分新增「選擇性撤銷(selective undo)」與「選擇性重複(selective repeat)」按鈕,且僅在可進行這些操作時啟用,否則應標為灰色。 * 點擊上述按鈕,會使右側命令列表中選取的命令選擇性的撤銷或重複,並將該操作放入撤銷歷史紀錄(因此他應出現在命令列表的末尾),且操作的名稱應該是合理的,例如 "selective repeat of change line border color to #ea3323" ## 評分標準 由於此作業包含多個部分,因此以下為不同功能所占分數,總分為 100 分(不包含加分)。 * 5 分:README * 95 分:網頁實作 * 20 分:整體實作與良好的程式碼風格 (coding style) * 75 分:撤銷/重做行為正確 * 25 分:實作線性撤銷模型 * 正確從撤銷堆疊 (stack) 中新增或刪除項目(6 分) * 執行一個以上的撤銷後,執行並非撤銷或重做的其他操作,那麼之前撤銷的操作不可被重做 (6 分) * 可以連續執行多個撤銷 (3 分) * 相應的使撤銷和重做按鈕變灰 (2 分) * 單擊以選取其他物件是不可撤銷的行為 (2 分) * 如選取的物件因撤銷或重做而改變,則操作面板的顏色、邊框寬度、邊框顏色… 等值,應符合改變後選取物件 (2 分) * 中止操作行為不改變任何狀態,因此不應影響撤銷堆疊 (2 分) * 在執行撤銷或重做後,請始終更改為選取模式 (2 分) * 50 分:5 項可撤銷的操作實作(每項 10 分) * 創建、更改填充顏色或邊框顏色、更改邊框寬度、移動、刪除 ## 繳交規範與截止期限 請訪問[此連結](https://classroom.github.com/a/JJ3jryix)以取得 HW5 起始程式碼,並遵照 `readme.md` 執行檔案,若有遇到任何問題請聯繫助教。 除了程式碼之外,請同時在 Repo 中新增 `README` 文件。該文件可以是純文字、markdown(建議)、Microsoft Word 或 pdf 格式。其中應包含: * 姓名 * 你所實作的網站如何被測試 * 你所實作的加分作業項目,以及如何觸發它 * 認為此作業最難實作的部分與原因 * 其他與軟體設計相關之感興趣內容 請在 **<font color="#f00">2023 年 05 月 10 日下午 23:59 (UTC+8)</font>** 之前將此文件連同程式碼提交至所開設的 repo。我們將以截止時間前最後一次提交的內容作為批改項目。 ###### tags: `使用者介面程式設計`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up