這篇文章給大家分享的是有關(guān)canvas中g(shù)lobalCompositeOperation屬性的示例分析的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序定制開發(fā)、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了陜西免費建站歡迎大家使用!
最早知道 canvas 的 globalCompositeOperation 屬性,是在需要實現(xiàn)一個刮刮卡效果的時候,當(dāng)時也就是網(wǎng)上找到刮刮卡的效果趕緊完成任務(wù)就完了,這次又學(xué)習(xí)一次,希望能加深理解吧。
先來看下 canvas 的 globalCompositeOperation屬性,具體是干什么的。
globalCompositeOperation 屬性設(shè)置或返回如何將一個源(新的)圖像繪制到目標(已有)的圖像上。
源圖像 = 您打算放置到畫布上的繪圖。
目標圖像 = 您已經(jīng)放置在畫布上的繪圖。
這個屬性用來設(shè)置要在繪制新形狀時應(yīng)用的合成操作的類型,比如在一個藍色的矩形上畫一個紅色的圓形,是紅色在上顯示,還是藍色在上顯示,重疊的部分顯示還是不顯示,不重疊的部分又怎么顯示,等一些情況,在面對這些情況的時候,就是 globalCompositeOperation
屬性起作用的時候了。
在取默認值的情況下,都是顯示的,新畫的圖形會覆蓋原來的圖形。
默認值: source-over
語法: context.globalCompositeOperation="source-in";
表格中的藍色矩形為目標圖像,紅色圓形為源圖像。
屬性值 | 描述 | 效果 |
---|---|---|
source-over | 默認。在目標圖像上顯示源圖像。 | ![]() |
source-atop | 在目標圖像頂部顯示源圖像。源圖像位于目標圖像之外的部分是不可見的。 | ![]() |
source-in | 在目標圖像中顯示源圖像。只有目標圖像內(nèi)的源圖像部分會顯示,目標圖像是透明的。 | ![]() |
source-out | 在目標圖像之外顯示源圖像。只會顯示目標圖像之外源圖像部分,目標圖像是透明的。 | ![]() |
destination-over | 在源圖像上方顯示目標圖像。 | ![]() |
destination-atop | 在源圖像頂部顯示目標圖像。源圖像之外的目標圖像部分不會被顯示。 | ![]() |
destination-in | 在源圖像中顯示目標圖像。只有源圖像內(nèi)的目標圖像部分會被顯示,源圖像是透明的。 | ![]() |
destination-out | 在源圖像外顯示目標圖像。只有源圖像外的目標圖像部分會被顯示,源圖像是透明的。 | ![]() |
lighter | 顯示源圖像 + 目標圖像。 | ![]() |
copy | 顯示源圖像。忽略目標圖像。 | ![]() |
xor | 使用異或操作對源圖像與目標圖像進行組合。 | ![]() |
好的,下來實現(xiàn)一個水滴擴散的效果:
https://codepen.io/FEWY/pen/oPxbmj
效果圖
實現(xiàn)思路
在一個 canvas 上先畫出黑白色的圖片,然后設(shè)置背景是一張彩色的圖片,鼠標點擊時,設(shè)置 canvas 的 globalCompositeOperation
屬性值為 destination-out
,根據(jù)鼠標在 canvas 中的 坐標,用一個不規(guī)則的圖形逐漸增大,來擦除掉黑白色的圖片,就可以慢慢顯示彩色的背景了。
也就是說我們需要三張圖片
黑白的圖片
彩色的圖片
不規(guī)則形狀的圖片
代碼
<!doctype html> <html> <head> <meta charset="UTF-8"> <style> canvas { /* 設(shè)置鼠標的光標是一張圖片, 16和22 分別表示熱點的X坐標和Y坐標 */ /* https://developer.mozilla.org/zh-CN/docs/Web/CSS/cursor/url */ cursor: url('https://www.kkkk1000.com/images/globalCompositeOperation/mouse.png') 16 22, auto; } </style> </head> <body> <canvas id="canvas" width="400px" height="250px"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); // 保存圖片路徑的數(shù)組 var urlArr = ["https://www.kkkk1000.com/images/globalCompositeOperation/bg2.png", "https://www.kkkk1000.com/images/globalCompositeOperation/clear.png"]; // imgArr 保存加載后的圖片的數(shù)組,imgArr中保存的是真實的圖片 // loadImg 函數(shù)用來加載 urlArr 中所有的圖片 // 并返回一個保存所有圖片的數(shù)組 var imgArr = loadImg(urlArr); // flag 用來限制 點擊事件,一張圖片只會產(chǎn)生一次效果 var flag = false; function loadImg(urlArr) { var index = 0; var res = []; // 每次給 load 函數(shù)傳入一個圖片路徑,來加載圖片 load(urlArr[index]); function load(url) { // 如果 index 等于 urlArr.length, // 表示加載完 全部圖片了,就結(jié)束 load函數(shù) if (index == urlArr.length) { // 加載完全部圖片,調(diào)用 init 函數(shù) init(); return; } var img = new Image(); img.src = url; // 不管當(dāng)前圖片是否加載成功,都要加載下一張圖片 img.onload = next; img.onerror = function () { console.log(res[index] + "加載失敗"); next(); } // next 用來加載下一張圖片 function next() { // 把加載后的圖片,保存到 res 中 res[index] = img; load(urlArr[++index]) } } // 最后返回保存所有真實圖片的數(shù)組 return res; } function init() { // 先在canvas上畫黑白的圖片,然后再設(shè)置背景是彩色的圖片 // 避免先顯示出彩色圖片,再顯示出黑白的圖片 context.globalCompositeOperation = "source-over"; context.drawImage(imgArr[0], 0, 0, 400, 250); canvas.style.background = 'url(https://www.kkkk1000.com/images/globalCompositeOperation/bg.jpg)'; canvas.style.backgroundSize = "100% 100%"; // flag 是 true 時,鼠標點擊才有水滴擴散的效果 flag = true; // canvas 綁定點擊事件,點擊時產(chǎn)生水滴擴散效果 canvas.onclick = diffusion; } // width 表示 不規(guī)則形狀的圖片的尺寸 var width = 0; // speed 表示擴散效果的速度 var speed = 8; // diffusion 函數(shù)根據(jù)鼠標坐標,產(chǎn)生效果 function diffusion (e) { if (flag) { flag = false; context.globalCompositeOperation = "destination-out"; window.requestAnimationFrame(draw); // 根據(jù)鼠標坐標,畫擴散效果 function draw() { // 這里不一定需要是 1800 ,但必須是一個足夠大的數(shù),可以擴散出整張背景圖 if (width > 1800) { flag = true; return; } width += speed; // 獲取鼠標相對于 canvas 的坐標 var x = e.layerX; var y = e.layerY; // 畫不規(guī)則形狀的圖片,逐漸增大圖片尺寸 context.drawImage(imgArr[1], x - (width / 2), y - (width / 2), width, width); window.requestAnimationFrame(draw); } } } </script> </body> </html>
我們繼續(xù)來實現(xiàn)一個刮刮卡的效果
效果圖
刮刮卡效果實現(xiàn)的思路:
一個 canvas 上先畫一層灰色,然后設(shè)置canvas的背景圖,設(shè)置 canvas 的 globalCompositeOperation
屬性值為 destination-out
,點擊并移動時,根據(jù)移動點的坐標,擦除掉灰色,當(dāng)擦掉一部分時,再自動擦除掉全部灰色,顯示出背景來。
刮刮卡的效果和水滴擴散的效果,在開始的時候幾乎是一樣的,不過水滴擴散效果,用的是一張不規(guī)則形狀的圖片來清除黑白圖片,而刮刮卡效果,是通過畫線的方式,線比較粗而已,來清除上面的灰色。
主要的不同是,刮刮卡效果最后需要自動擦除掉全部灰色,這里有兩種方式。
第一種
使用 canvas 的 getImageData 方法,來獲取 canvas 上的像素信息,這個方法返回的對象的 data 屬性是一個一維數(shù)組,包含以 RGBA 順序的數(shù)據(jù),數(shù)據(jù)使用 0 至 255(包含)的整數(shù)表示,詳細的可以看看 canvas 的像素操作。
用這個方法來判斷有多少已經(jīng)擦除掉了,也就是通過一個變量來記錄有多少像素的RGBA的值是0,當(dāng)變量的值超過某一個值時,就清除全部灰色。
代碼在這里:
https://codepen.io/FEWY/pen/BOjmyg
第二種
就直接看移動了多少,鼠標移動時,會有一個變量進行自增運算,當(dāng)這個變量,超過一定值時,就擦除全部灰色。
代碼在這里
https://codepen.io/FEWY/pen/eLJeNv
注意:
第一種方式使用 getImageData 存在跨域問題,不過因為這個效果中,沒有在canvas上畫圖片,而是設(shè)置canvas的 background
為一張圖片,所以這個還沒有影響,但是如果canvas上畫了其他圖片,就可能需要處理跨域的問題了。
使用 getImageData 能獲取到 canvas 上的像素信息,就可以根據(jù)刮刮卡上灰色的面積,決定擦除全部灰色的時機,更加靈活。
第二種方式,雖然不存在跨域的問題,但是,不能很好的根據(jù)刮刮卡上灰色的面積,控制最后擦除全部灰色的時機。
感謝各位的閱讀!關(guān)于“canvas中g(shù)lobalCompositeOperation屬性的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
分享名稱:canvas中g(shù)lobalCompositeOperation屬性的示例分析
當(dāng)前地址:http://sd-ha.com/article32/jsjisc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、外貿(mào)網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計、搜索引擎優(yōu)化、手機網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)