# HW3 使用 SVG 與 Canvas 繪製圖像 如想直接獲得起始程式碼並建立倉儲 (repository),請點擊[此連結](https://classroom.github.com/a/s4qKYGb2) 請在 **<font color="#f00">2023 年 04 月 15 日下午 23:59 (UTF+8)</font>** 之前將此文件連同程式碼提交至所開設的 repo。我們將以截止時間前最後一次提交的內容作為批改項目。 在作業三中,請創建一個簡單的圖形編輯器,但較為困難的是該編輯器需 **同時支持使用 SVG (向量圖) 與 Canvas(點陣圖,類似小畫家)** 所組成的圖像。 由於他們彼此互不兼容,因此將位於不同圖層上,而使用者可以單獨打開或關閉,並且依次只能在一個圖層上查看與編輯,某種程度上類似於像 Photoshop 一般的混合編輯器。 <!-- 確保在處理作業 3 時不要打擾 Github 上的 HW2 文件,因為我們需要訪問 HW2 才能對其進行評分。 --> 請從此連結中複製作業三的起始程式碼,與前兩個作業一樣,請**不要使用外部函式庫**,僅使用常規 Javascript, HTML 和 CSS 撰寫。 <!-- 您正在創建的編輯器可從作業 1 網頁的頁眉,但除非您願意,否則不需要從那裡鏈接它。希望您在家庭作業 2 中的代碼將有助於實現家庭作業 3 的行為。 --> ## 作業概述與可用資源 我們會提供 `floodfill.js` (填充功能)的已實作檔案,因此你不需要了解詳細運行原理。 該作業的起始程式碼將包含以下資料夾與文件: * `assets/` - 包含兩個可用於模式選單圖片檔案的資料夾: * `cursor.png` - 游標的圖片 * `line.png` - 線條的圖片(用於加分項目,詳情請參考以下章節) * `floodfills.js` - 實作填充顏色 (floodfill) 的檔案,可能可用於作業三實作中。 此外,請瀏覽以下圖片和影片,以了解具體規範: * [`hw3-example.mp4`](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/hw3-example.mp4) - 一段說明作業三應有的模樣與事件的影片 * [`HW3-example-selected-circle-svg.png`](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/HW3-example-selected-circle-svg.png) - SVG 模式示意圖,圖中呈現繪製些許圖形、選取圓圈...等行為 * [`HW3-example-canvas-flood-fill.png`](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/HW3-example-canvas-flood-fill.png) - Canvas 模式示意圖,圖中呈現使用灰色填充物件間空間的行為 * [`HW3-example-both-mode.png`](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/HW3-example-both-mode.png) - 同時打開兩個圖層 (SVG, Canvas)時,SVG 圖層永遠在最上面 * [`HW3-example-svg-rect-selected.png`](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/HW3-example-svg-rect-selected.png) - 當選取一個矩形時,其會以圖形後陰影方式呈現 * [`HW3-example-svg-line-selected.png`](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/HW3-example-svg-line-selected.png) - 當選取一個線條時,其會以線條後陰影方式呈現(線條為加分作業) ## 詳細要求 如同作業一,你不需要讓作業的實作與上章提供的圖片與影片達到像素級的一致,但你需要讓作業三的網頁中可進行的行為看起來、操作起來與範例影片盡可能相同。如果作業敘述上有些模糊,或是你的實作可能會偏離定義行為,請以信件或 NTU COOL 詢問助教。 以下為詳細要求: * 畫面左方為操作面板,而右方則為工作區域,工作區域包含以 Canvas 覆蓋的滿版圖層,以及以 SVG 覆蓋的滿版圖層,請將 SVG 滿版圖層放置於最上方。 * 由於將滿版圖層的長寬固定是可被接受的,因此當縮放頁面時,可**允許使用者需要透過滑動以瀏覽整個圖層**。 * 操作面板須符合以下控制項: * **圖層 (Layer)**:決定哪個圖層(SVG, Canvas)是可見、可被操控的。這會是只允許一個選項的單選按鈕。選項如下: * **顯示 Canvas 圖層**:僅顯示 Canvas 圖層及其所有內容,並且讓使用者可在此圖層及在此圖層上的物件進行操作。 * **顯示 SVG 圖層**:僅顯示 SVG 圖層及其所有內容,並且讓使用者可在此圖層及在此圖層上的物件進行操作。 * 顯**示兩個圖層**:顯示 Canvas(底部)和 SVG(頂部)圖層,但**皆不允許編輯任何圖層**(由於所有其他控制項都應該是不可操作的,因此應以灰色呈現)。 * **模式 (Mode)**:決定當使用者在工作區中使用滑鼠或手指與其互動時會發生的情況,應透過周圍的圓角藍色框表示當前選取的模式。可選取的模式如下: * **選取 (游標)**: * 當僅 SVG 圖層被打開時,其可用於選取物件 * 當僅 Canvas 圖層被打開時,其可用於填充物件顏色 * **矩形**: * 在 SVG 與 Canvas 圖層皆可用於繪製矩形,邊框顏色、線條粗細,與填充顏色皆由畫面中被選取的選項所決定。 * 此模式應為每次進入頁面時的預設模式。 * 請注意: * 當填充顏色被設定為「無」時,矩形內不會被填色,這代表應顯示該圖矩形底下的其他物件 * 當邊框顏色被設定為「無」時,代表此矩形沒有邊框 * 不允許同時設定填充顏色與邊框顏色為「無」(不可能存在看不到的物件) * **橢圓形**: * 請以類似於繪製矩形的做法,透過定義左上和右下角來繪製橢圓形(注意:請不要透過定義中心和半徑實作此部分) * **線條**: * 此模式為加分項目,詳細資訊會在接下來的部分做陳述。若沒有打算實作線條,請在操作面板中刪除此部分。 * **邊框** * 請提供至少七種顏色與「無」之邊框選項,並使用和「模式」區塊中相同的樣式,表示當前選取的顏色。 * 預設顏色為黑色。 * 由於不可將填充與邊框顏色同時設定為「無」,因此當填充顏色為無時,請忽略使用者設定邊框顏色為無的行為。 * **邊框寬度** * 使用 `input type="range"` 讓使用者可設定邊框寬度為 1px 至 30px。 * 預設寬度為 3px。 * 這邊的設定需同時套用至矩形、橢圓形與線條。 * **填充** * 請提供至少七種顏色與「無」之填充選項,並使用和「模式」區塊中相同的樣式,表示當前選取的顏色。 * 預設顏色為綠色。 * 由於不可將填充與邊框顏色同時設定為「無」,因此當邊框顏色為無時,請忽略使用者設定填充顏色為無的行為。 * **選單** * 請實作一個「刪除」按鈕,該按鈕僅在 SVG 模式時選取一個物件時啟用,用途為刪除選取物件。 當不在SVG 模式或未選取物件時,請讓按鈕反灰。 * 請實作一個「刪除全部」按鈕,用途為刪除 SVG 和 Canvas 圖層上的所有物件。在兩種圖層皆無任何內容時,可以讓此按鈕仍可被使用,並在點選後什麼都不做。 * 當圖層為 SVG 或 Canvas ,且模式被設定為繪圖(矩形、橢圓或線條)時,按下滑鼠 (mousedown) 時開始繪製圖形,拖動滑鼠時需要實時反饋,且放開滑鼠 (mouseup) 時完成圖形。此繪製圖形應使用當前選取的顏色和邊框寬度。 * 提示:在拖曳滑鼠繪製圖形時,由於在確定形狀最終尺寸前,無法將其直接繪製在圖層中,因此需要**使用額外圖層實作實時反饋**。 * 提示:在 SVG 圖層時,需要儲存所有創建物件與其屬性,以讓使用者可在需要時編輯單一物件。 * 請不要讓使用者可繪製不可見的物件:只有在物件大於最小尺寸時才可被成功繪製 * 最小尺寸 * 橢圓、矩形:10px x 10px * 線條:10px * 提示:此部分僅能在操作結束 (mouseup) 時被檢查,這代表當使用者拖曳滑鼠時,即使當前物件尺寸過小,也不要中止其動作。 * 在拖曳繪製物件時點選 ESC 或多放置一根手指時,應中止當前操作、移除實時反饋且不會出現繪製完成的物件,這與作業二中的中止方式類似。 * 無論是在 SVG 或 Canvas 圖層上繪製物件,他們看起來需幾乎相同(除了課程中所提到的矩形和橢圓邊框寬度差異) * 當物件繪製完成時,請不要同時讓該物件處於被選取的狀態,或讓模式改為選取(游標),而是持續繪製模式。 * 當圖層為 SVG 且模式為選取(游標)時,點選物件將使其變為被選取狀態。在作業二時,點選物件可改變顏色,但此功能在此作業中並不合適。真正的圖形編輯器在游標處於物件角落時,但這有點複雜(請參考加分資訊),因此只需在選取物件時,以陰影方式呈現被選取狀態。(請參考[矩形](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/HW3-example-svg-rect-selected.png)、[線條](https://www.cs.cmu.edu/~bam/uicourse/05631fall2022/HW3/HW3-example-svg-line-selected.png)示意圖) * 提示:添加陰影至物件上的方式為 `object.setAttribute("filter", url(#${shadowFilterId}))`,請參考[此網頁](https://www.w3schools.com/graphics/svg_feoffset.asp)以獲得更多資訊。 * 當使用者點選物件時,操作面板中的顏色與邊框寬度將與被點選的物件相同。例如:當點選紅色、藍色 4px 邊框的矩形時,無論先前的內容為何,選單中的邊框顏色需變成藍色、寬度變成 4px,且填充顏色變成紅色。 * 點選背景時將如同作業二一般取消選取,且不改變操作面板中的任何內容(顏色與邊框寬度) * 當選取物件後,如果在操作面板上更改顏色或邊框寬度,被選取物件應有相應改變以符合操作面板設定。同樣的,不可將邊框或填充顏色都設定為無色。 * 從選取模式切換到繪圖模式(矩形、橢圓與線條)時,將使圖層上沒有任何東西被選取。 * 當圖層模式從 SVG 切換為 Canvas 或混合時,將使圖層上沒有任何東西被選取,而從其他模式轉換成 SVG 圖層時亦然。 * 當圖層為 SVG 且模式為選取時,在物件上按下滑鼠 (mousedown)並拖曳時,將如作業二一樣移動物件,直到放開滑鼠 (mouseup)。 * 如果在拖曳物件時尚未選取物件,那麼在物件在開始移動前會轉變為被選取狀態,並在拖曳結束後持續此狀態(且操作面板上的顏色、邊框寬度值應與當前拖曳的物件值相同) * 如果使用者在移動物件時同步按下 ESC,那當前移動將中止並返回到他開始的地方(如同作業二),並且在放開滑鼠 (mouseup)前將不會有任何進一步動作。 * 當中止動作時,物件的被選取狀態將同步被取消 * 不需要實作作業二中的雙擊功能。 * 當圖層為 Canvas,並且模式為選取時,可點選圖層以使用當前選取的填充顏色[填充](https://en.wikipedia.org/wiki/Flood_fill)。此操作在小畫家中通常由傾斜的油漆罐表示,這意味著從單擊的像素開始,使所有具有該顏色的相鄰像素成為新顏色。填充的實作已定義於 `floodfill.js`,因此只需將該檔案與的其他程式碼集成 (integrate)即可。 * 提示:此算法並沒有完美處理抗鋸齒 (anti-aliasing),僅實作精確匹配,因此如果填充區域周圍有白色邊框是可被接受的。另外,由於這個算法不是特別有效率,因此需要一段時間才能填充一個大區域也是可被接受的。 * 提示:不要試圖填充物件之外的區域(填充整個工作區大約需要 30 秒!),在 floodFill 函數中實作了等待的游標效果,以讓使用者了解緩慢的操作正在進行中。 * **不需要**支持作業二的任何**觸控行為**,也就是不需要處理任何觸控事件。除非你計畫實作加分作業,否則在這份作業中允許沒有辦法改變物件大小。如果想引入作業二中的程式碼以實作觸控事件,那麼這些實作將計入加分項目(見下文)。 ## 加分作業 * **線條繪製與移動(最多在此作業中+10分)** * 在操作面板上新增線條繪製模式,以讓使用者可在 Canvas 或 SVG 圖層上繪製線條。在任何情況下,線條的顏色與寬度需符合當前在操作面板上的選取。 * 注意:如果邊框顏色為無,則不可繪製線條。 * 讓使用者可透過邊框顏色和寬度的選取以更改繪製線條的屬性,且在 SVG 圖層選取線條時,操作面板上顯示的邊框顏色和寬度需和所選取線條的屬性相同。 * 當選取線條時,將邊框顏色改為無,將不會觸發任何動作。 * 當線條在 SVG 圖層中被選取時,請實作先前章節所述的陰影效果。 * 當拖曳移動線條時,請改變他的位置而非斜度,這代表線條的兩個端點薑一起移動。 * **框選功能(最多在此作業中+3分)** * 如果在作業二中實作了框選功能,那在此處實作該功能將也能獲得加分。(請參考[作業二第二項加分項目](https://hackmd.io/@akairisu/HkUibgmx3#%E5%8A%A0%E5%88%86%E9%A0%85%E7%9B%AE)) * **使用選取手柄 (selection handle) 標示被選取項目(最多在此作業中+8分)** * 在顯示當前被選取物件時,比起利用陰影呈現,更好的方式是如同PowerPoint 或 Google Slides,利用空心方塊(選取手柄)呈現。你可以在矩形和橢圓的角和邊的中心使用 4 或 8 個小正方形/圓形,並在線條中使用 2 或 3 個小正方形/圓形。 (+3分)  * 如果同時允許使用者可透過屬標或手指拖曳手柄以更改物件大小,並符合先前提及的最小尺寸限制,那麼最多可再+5分。 * **其他繪圖模式(最多在此作業中+9分)** * 可實作折線 (polyline) 繪製、徒手繪製 (free-hand drawing/inking) ,或利用本地文件或 URL 上傳圖片。這些必須在 SVG 與 Canvas 圖層中均可被使用。 * **其他操作(最多在此作業中+10分)** * 為 SVG 或 Canvas 圖層或兩者新增其他操作,在真正的圖形編輯器中有很多操作可供選取。根據操作複雜性,每次加法可能是 +2 到 +5。 * **觸控操作(最多在此作業中+8分)** * 讓觸控和滑鼠呈現相同動作,例如:在控制面板中選取、在 SVG 和 Canvas 圖層中繪製物件、在 SVG 圖層中移動、使用額外手指的觸控中止當前動作 (+5) * 使用兩根手指水平調整物件大小 (+2) * 使用兩根手指垂直調整物件大小 (+1) ## 評分標準 由於此作業包含多個部分,因此以下為不同功能所占分數,總分為 100 分(不包含加分)。 * 5 分:README * 95 分:網頁實作 * 10 分:整體實作與良好的程式碼風格 (coding style) * 10 分:操作面板功能正常 * 44 分:SVG 圖層功能正常 * 2 分:可根據操作面板的圖層控制項,成功顯示 / 隱藏 SVG 物件 * 20 分:新增物件 * 8 分:選取物件 * 4 分:移動物件 * 6 分:更改顏色跟邊框寬度 * 2 分:刪除物件 * 2 分:刪除所有 SVG 物件 * 31 分:Canas 圖層功能正常 * 2 分:可根據操作面板的圖層控制項,成功顯示 / 隱藏 Canvas 物件 * 20 分:新增物件 * 2 分:當更改顏色或線條寬度時,不會改變現有新增中的物件,但可用於下一個新增物件 * 2 分:刪除所有 Canvas 物件 * 5 分:填充物件內部顏色 ## 使用 GitHub Repo 設定 * **請點擊[此連結](https://classroom.github.com/a/s4qKYGb2)以獲得 HW3 起始程式碼並建立倉儲** (repository) * 可下載 Github Desktop,以便在本機端輕鬆編輯程式碼並將更改提交到 Github ## 繳交規範與截止期限 除了程式碼之外,請同時在 Repo 中新增 `README` 文件。該文件可以是純文字、Microsoft Word、markdown 或 pdf 格式。其中應包含: * 姓名 * 你所實作的網站如何被測試 * 你所實作的加分作業項目,以及如何觸發它 * 認為此作業最難實作或 debug 的部分與原因 * 其他你所實作的網站的有趣之處 請在 **<font color="#f00">2023 年 04 月 15 下午 23:59 (UTF+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