公司國慶搞了個集卡、抽獎小活動。抽獎須要刮刮卡的效果,感受 css 是實現不了。看我使用 canvas 如何實現刮刮卡效果。
廢話很少說,線上效果 jsrun-測試地址 、 lilnong.top-測試地址css
clearRect
這是我第一個找到的 API,做用是清除一個矩形區域內的內容。缺點是矩形 globalCompositeOperation
基於上面的缺點,我發現了他 destination-out
是我須要的,做用是改變canvas圖形的混合模式 context.fillStyle = color;
)drawImage
來繪製畫布)自定義筆觸html
clearRect
爲矩形arc
配合globalCompositeOperation
來實現圓形drawImage
配合globalCompositeOperation
來自定義筆觸兩個方案的差距不大,根據我的喜愛選擇便可。前端
方案一 DOM 層級(擁有更多的能力)效果查看-傳送門canvas
<style type="text/css"> #app1{width:300px;height:100px;position: relative;border: 1px solid #f00;} #app1Content{width:300px;height:100px;position: absolute;left:0;top:0;z-index: 1} #app1Mark{width:300px;height:100px;position: absolute;left:0;top:0;z-index: 2} </style> <div id="app1"> <div id="app1Content" style="background:url(https://www.lilnong.top/static/img/ml-btn6.png) left center no-repeat">我是自定義內容</div> <canvas id="app1Mark"></canvas> </div>
方案二 canvas 背景圖(使用簡單)效果查看-傳送門api
<style type="text/css"> #app2{width:300px;height:100px;position: relative;border: 1px solid #f00;} #app2Mark{width:300px;height:100px;position: absolute;left:0;top:0;z-index: 2} </style> <div id="app2"> <canvas id="app2Mark" style="background:url(https://www.lilnong.top/static/img/ml-btn6.png) left center no-repeat"></canvas> </div>
ctx.fillStyle = '#0cc';
主要經過這個來設置填充樣式。效果查看-傳送門
感興趣能夠去看看,我這裏沒用到就不細說了。傳送門 - Canvas API中文網微信
色值填充app
RGB(255, 0, 0)
HSL(360, 100%, 50%)
RGBA(255, 0, 0, .5)
HSLA(360, 100%, 50%, .5)
#FF0000
createLinearGradient()
createRadialGradient()
createPattern
ctx = app3Mark.getContext('2d'); app3Mark.width = 300; app3Mark.height = 100; ctx.moveTo(0, 0); ctx.lineTo(app3Mark.width, 0); ctx.lineTo(app3Mark.width, app3Mark.height); ctx.lineTo(0, app3Mark.height); ctx.fillStyle = '#0cc'; ctx.fill();
drawImage()
使用這個方法來繪製一個圖片,須要等圖片onload以後再使用
效果查看-傳送門測試
ctx = app4Mark.getContext('2d'); app4Mark.width = 300; app4Mark.height = 100; var imageFill = new Image(); imageFill.src = 'https://www.lilnong.top/static/img/defaultmatch.png' app4MarkCtx = ctx; imageFill.onload = function(){ app4MarkCtx.drawImage(this,0,0,300,100) }
clearRect
方案 效果傳送門context.clearRect(x, y, width, height);
將畫布某一塊矩形區域內容清除。globalCompositeOperation
方案 效果傳送門
設置繪製時,圖形的混合模式。傳送門-canvas api,其實好多我都沒用過,太難了,PS中的我不怎麼會用。destination-*
區別是動做的主體是新內容仍是原內容。source-*
系列是新內容,而destination-*
系列動做主體是原內容。this
source-over
默認值,表現爲覆蓋。純視覺覆蓋。source-in
表現爲在原內容上繪製,顯示重疊部分,透明度疊加。source-out
與source-in
對應,表現爲減去原內容。source-atop
表現爲在原內容上繪製,使用原內容透明度。destination-over
表現爲原內容在上方,新內容在下方繪製。destination-in
同理,表現爲透明度疊加,顯示重疊部分。destination-out
同理,隱藏原內容和新內容重疊的部分。destination-atop
原內容只顯示和新內容重疊的部分,同時新內容在下方顯示lighter
天然光混合效果copy
只顯示新內容xor
重疊區域爲透明multiply
正片疊底。頂層的像素與底層的對應像素相乘。結果是一幅更黑暗的圖畫screen
濾色。像素反轉,相乘,而後再反轉。最終獲得更淡的圖形(和 multiply 相反)overlay
疊加。 multiply 和 screen 組合效果。基礎圖層上暗的部分更暗,亮的部分更亮darken
變暗。保留原內容和新內容中最暗的像素lighten
變亮。保留原內容和新內容中最亮的像素color-dodge
顏色減淡。底部圖層色值除以頂部圖層的反相色值color-burn
顏色加深。底部圖層的色值除以頂部圖層色值,獲得的結果再反相hard-light
強光。相似 overlay,是 multiply 和 screen 組合效果。只不過底層和頂層位置交換下soft-light
柔光。hard-light 的柔和版本。純黑色或白色不會生成爲純黑色或白色。difference
差別。頂層色值減去底層色值的絕對值。若是都是白色,則最後是黑色,由於值爲0;何時是白色呢,例如RGB(255,0,0)和RGB(0,255,255),色值相減後絕對值是RGB(255,255,255)。exclusion
排除。相似difference,不過對比度較低。hue
色調。最終的顏色保留底層的亮度和色度,同時採用頂層的色調。saturation
飽和度。最終的顏色保留底層的亮度和色調,同時採用頂層的色度。color
色值。最終的顏色保留底層的亮度,同時採用頂層的色調和色度。luminosity
亮度。最終的顏色保留底層的色調和色度,同時採用頂層的亮度。先來看咱們刪除的代碼。其實依靠的就是x
和y
的座標值。那麼咱們抽一個clear的方法,傳遞座標。把每次單擊的點都記錄一下,而後循環把點推動去不就是自動的了嗎?url
app6Mark.addEventListener('mousedown', function(e){ app6MarkMouseDownTag = 1 app6MarkCtx.fillText('lilnong.top', e.offsetX - 50, e.offsetY+10); })
getImageData
返回一個ImageData
對象,其中包含Canvas畫布部分或完整的像素點信息
。通道透明數/總循環數
就是刮開面積佔比var imageData = ctx.getImageData(0, 0, 300, 200).data; var eraseTotal = 0; var step = 1 * 4;//步長精度 for (var i = 3, len = imageData.length; i < len; i += step) { if (imageData[i] === 0) { eraseTotal++; } } eraseRate.innerText = eraseTotal/(len/step)
mousemove
要注意節流