# Canvas 關於橡皮擦 ### HTML DOM classList 屬性 :::info classList 屬性返回元素的類名,作為 DOMTokenList 對象。 該屬性用於在元素中添加,移除及切換 CSS 類。 classList 屬性是只讀的,但你可以使用 add() 和 remove() 方法修改它。 ::: * add ->在元素中添加一個或多個類名。如果指定的類名已存在,則不會添加 * remove ->移除元素中一個或多個類名。注意: 移除不存在的類名,不會報錯。 * [更多方法在此](https://www.runoob.com/jsref/prop-element-classlist.html) * [更多方法在此](https://ithelp.ithome.com.tw/articles/10241358) ```javascript= // 觸發橡皮擦 toolbar.addEventListener("click", (e) => { if (e.target.id === "eraser") { eraserEnabled = true // 透過 active 進行切換橡皮擦跟畫筆,使用橡皮擦->開,畫筆->關 eraser.classList.add("active") brush.classList.remove("active") ctx.globalCompositeOperation = "destination-out" } if (e.target.id === "brush") { eraserEnabled = false eraser.classList.remove("active") brush.classList.add("active") ctx.globalCompositeOperation = "source-over" } }) ``` ### globalCompositeOperation -> [合成效果](https://developer.mozilla.org/zh-TW/docs/Web/API/Canvas_API/Tutorial/Compositing) :::info 新繪製的圖形總會覆蓋在之前的圖形上,對大多數情況來說這相當正常,不過它也限制了圖形繪製的順序。其實我們可以透過 globalCompositeOperation 屬性來改變這項預設行為。 ::: 利用 globalCompositeOperation, 我們可以將新圖形繪製在舊圖形之下、 遮蓋部分區域、清除畫布部分區域 (不同於 clearRect() 函式只能清除矩形區域)。 **globalCompositeOperation 屬性** 將一個源(新的)圖像繪製到目標(已有的)的圖像上。 :::info 源圖像 = 打算放置到畫布上的繪圖。 目標圖像 = 已經放置在畫布上的繪圖。 ::: ```javascript= var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.fillStyle="blue"; ctx.fillRect(20,20,75,50); ctx.fillStyle="red"; ctx.globalCompositeOperation="source-over"; ctx.fillRect(50,50,75,50); ``` 先執行藍色區域,再增添紅色矩形 -> globalCompositeOperation="source-over" 超越舊的代表 -> 舊的落後在後面 ![](https://i.imgur.com/k9IPn3j.png =200x) **globalCompositeOperation = type** [type 可指定為以下多種合成設定之一](https://www.w3big.com/zh-TW/tags/canvas-globalcompositeoperation.html#gsc.tab=0) 每一種合成設定均將套用到新繪製的圖形上。 ```javascript= var gco=new Array(); gco.push("source-atop");在目標圖像頂部顯示源圖像。源圖像位於目標圖像之外的部分是不可見的。 gco.push("source-in");在目標圖像中顯示源圖像。只有目標圖像之內的源圖像部分會顯示,目標圖像是透明的。 gco.push("source-out");在目標圖像之外顯示源圖像。只有目標圖像之外的源圖像部分會顯示,目標圖像是透明的。 gco.push("source-over");默認。在目標圖像上顯示源圖像。 gco.push("destination-atop");在源圖像頂部顯示目標圖像。目標圖像位於源圖像之外的部分是不可見的。 gco.push("destination-in");在源圖像中顯示目標圖像。只有源圖像之內的目標圖像部分會被顯示, 源圖像是透明的。 gco.push("destination-out");在源圖像之外顯示目標圖像。只有源圖像之外的目標圖像部分會被顯示,源圖像是透明的。 gco.push("destination-over");在源圖像上顯示目標圖像。 gco.push("lighter");顯示源圖像 + 目標圖像。 gco.push("copy");顯示源圖像。忽略目標圖像。 gco.push("xor");使用異或操作對源圖像與目標圖像進行組合。 ...... ctx.fillStyle="blue"; ctx.fillRect(10,10,50,50); ctx.globalCompositeOperation=gco[n]; ctx.beginPath(); ctx.fillStyle="red"; ctx.arc(50,50,30,0,2*Math.PI); ctx.fill(); ......先有藍方->目標圖像(舊的) 才有紅圈 -> 源圖像(新) ``` ![](https://i.imgur.com/zJHeqXc.png =600x)