目錄
說明" >說明
定義" >定義
用法" >用法
首頁 web前端 H5教程 帶你了解canvas中的globalCompositeOperation屬性

帶你了解canvas中的globalCompositeOperation屬性

Apr 25, 2021 am 11:57 AM
canvas javascript

這篇文章帶大家詳細了解canvas中的globalCompositeOperation屬性,透過程式碼實例看看該屬性所做的神奇效果。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

帶你了解canvas中的globalCompositeOperation屬性

說明

#最早知道canvas 的globalCompositeOperation 屬性,是需要實現一個刮刮卡效果的時候,當時也就是網路上找到刮刮卡的效果趕緊完成任務就完了,這次又學習一次,希望能加深理解吧。

先來看下 canvas 的 globalCompositeOperation屬性,具體是做什麼的。

定義

globalCompositeOperation 屬性設定或傳回如何將一個來源(新的)影像繪製到目標(已有)的圖像上。
來源圖像 = 您打算放置到畫布上的繪圖。
目標圖像 = 您已經放置在畫布上的繪圖。

這個屬性用來設定要在繪製新形狀時應用的合成操作的類型,例如在一個藍色的矩形上畫一個紅色的圓形,是紅色在上顯示,還是藍色在上顯示,重疊的部分顯示還是不顯示,不重疊的部分又怎麼顯示,等一些情況,在面對這些情況的時候,就是globalCompositeOperation 屬性起作用的時候了。
在取預設值的情況下,都是顯示的,新畫的圖形會覆蓋原來的圖形。

用法

預設值: source-over
語法: context.globalCompositeOperation=" source-in";

表格中的藍色矩形為目標影像,紅色圓形為來源影像。

屬性值 描述 效果
source-over 預設.在目標影像上顯示來源影像。
source-atop 在目標影像頂部顯示來源影像。來源影像位於目標影像之外的部分是不可見的。
source-in 在目標影像中顯示來源影像。只有目標影像內的來源影像部分會顯示,目標影像是透明的。
source-out 在目標影像之外顯示來源影像。只會顯示目標影像之外來源影像部分,目標影像是透明的。
destination-over #在來源影像上方顯示目標影像。
destination-atop #在來源影像頂部顯示目標影像。來源影像之外的目標影像部分不會被顯示。
destination-in #在來源影像中顯示目標影像。只有來源影像內的目標影像部分會被顯示,來源影像是透明的。
destination-out #在來源影像外顯示目標影像。只有來源影像外的目標影像部分會被顯示,來源影像是透明的。
lighter 顯示來源影像 目標影像。
copy 顯示來源影像。忽略目標影像。
xor 使用異或運算對來源影像與目標影像進行組合。

好的,下來實現一個水滴擴散的效果:

https://codepen.io/FEWY/pen/oPxbmj

效果圖

實現想法

#在一個canvas 上先畫出黑白色的圖片,然後設定背景是一張彩色的圖片,滑鼠點擊時,設定canvas 的globalCompositeOperation 屬性值為destination-out,根據滑鼠在canvas 中的座標,用一個不規則的圖形逐漸增大,來擦除掉黑白色的圖片,就可以慢慢顯示彩色的背景了。

也就是說我們需要三張圖片

黑白的圖片

帶你了解canvas中的globalCompositeOperation屬性

彩色的圖片

帶你了解canvas中的globalCompositeOperation屬性

不規則形狀的圖片

帶你了解canvas中的globalCompositeOperation屬性

程式碼

<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <style>
        canvas {
            /* 设置鼠标的光标是一张图片, 16和22 分别表示热点的X坐标和Y坐标 */
            /* https://developer.mozilla.org/zh-CN/docs/Web/CSS/cursor/url */
            cursor: url(&#39;https://www.kkkk1000.com/images/globalCompositeOperation/mouse.png&#39;) 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");

        // 保存图片路径的数组
        var urlArr = ["https://www.kkkk1000.com/images/globalCompositeOperation/bg2.png", "https://www.kkkk1000.com/images/globalCompositeOperation/clear.png"];
        // imgArr 保存加载后的图片的数组,imgArr中保存的是真实的图片
        // loadImg 函数用来加载 urlArr 中所有的图片
        // 并返回一个保存所有图片的数组
        var imgArr = loadImg(urlArr);
        // flag 用来限制 点击事件,一张图片只会产生一次效果
        var flag = false;
 

        function loadImg(urlArr) {
            var index = 0;
            var res = [];
            // 每次给 load 函数传入一个图片路径,来加载图片
            load(urlArr[index]);
            function load(url) {
                // 如果 index 等于 urlArr.length,
                // 表示加载完 全部图片了,就结束 load函数
                if (index == urlArr.length) {
                    // 加载完全部图片,调用 init 函数
                    init();
                    return;
                }

                var img = new Image();
                img.src = url;
                // 不管当前图片是否加载成功,都要加载下一张图片
                img.onload = next;
                img.onerror = function () {
                    console.log(res[index] + "加载失败");
                    next();
                }
                // next 用来加载下一张图片
                function next() {
                    // 把加载后的图片,保存到 res 中
                    res[index] = img;
                    load(urlArr[++index])
                }
            }
            // 最后返回保存所有真实图片的数组
            return res;
        }

        function init() {
            // 先在canvas上画黑白的图片,然后再设置背景是彩色的图片
            // 避免先显示出彩色图片,再显示出黑白的图片
            context.globalCompositeOperation = "source-over";
            context.drawImage(imgArr[0], 0, 0, 400, 250);
            canvas.style.background = &#39;url(https://www.kkkk1000.com/images/globalCompositeOperation/bg.jpg)&#39;;
            canvas.style.backgroundSize = "100% 100%";

            // flag 是 true 时,鼠标点击才有水滴扩散的效果
            flag = true;
            // canvas 绑定点击事件,点击时产生水滴扩散效果
            canvas.onclick =  diffusion;
        }

        // width 表示 不规则形状的图片的尺寸
        var width = 0;
        // speed 表示扩散效果的速度
        var speed = 8;
        // diffusion 函数根据鼠标坐标,产生效果
        function  diffusion (e) {
            if (flag) {
                flag = false;
                context.globalCompositeOperation = "destination-out";
                window.requestAnimationFrame(draw);
                // 根据鼠标坐标,画扩散效果
                function draw() {
                    // 这里不一定需要是 1800 ,但必须是一个足够大的数,可以扩散出整张背景图
                    if (width > 1800) {
                        flag = true;
                        return;
                    }
                    width += speed;
                    // 获取鼠标相对于 canvas 的坐标
                    var x = e.layerX;
                    var y = e.layerY;

                    // 画不规则形状的图片,逐渐增大图片尺寸
                    context.drawImage(imgArr[1], x - (width / 2), y - (width / 2), width, width);
                    window.requestAnimationFrame(draw);
                }
            }
        }
    </script>
</body>

</html>
登入後複製

我們繼續實現一個刮刮卡的效果

效果圖

帶你了解canvas中的globalCompositeOperation屬性

刮刮卡效果實現的想法:

一個canvas 上先畫一層灰色,然後設定canvas的背景圖,設定canvas 的globalCompositeOperation屬性值為destination -out,點擊並移動時,根據移動點的座標,擦除掉灰色,當擦掉一部分時,再自動擦除掉全部灰色,顯示出背景來。

刮刮卡的效果和水滴擴散的效果,在開始的時候幾乎是一樣的,不過水滴擴散效果,用的是一張不規則形狀的圖片來清除黑白圖片,而刮刮卡效果,是透過畫線的方式,線比較粗而已,來清除上面的灰色。
主要的不同是,刮刮卡效果最後需要自動擦除掉全部灰色,這裡有兩種方式。

第一種

使用canvas 的getImageData 方法,來取得canvas 上的像素信息,這個方法傳回的物件的data 屬性是一個一維數組,包含以RGBA 順序的數據,數據使用0 至255(包含)的整數表示,詳細的可以看看canvas 的像素操作
用這個方法來判斷有多少已經擦除掉了,也就是透過一個變數來記錄有多少像素的RGBA的值是0,當變數的值超過某一個值時,就清除全部灰色。

程式碼在這裡:

##https://codepen.io/FEWY/pen/BOjmyg

第二種

就直接看移動了多少,滑鼠移動時,會有一個變數進行自增運算,當這個變量,超過一定值時,就擦除全部灰色。

程式碼在這裡

https://codepen.io/FEWY/pen/eLJeNv

注意: 第一種方式使用
getImageData 存在跨域問題,不過因為這個效果中,沒有在canvas上畫圖片,而是設定canvas的background 為一張圖片,所以這個還沒有影響,但如果canvas畫了其他圖片,就可能需要處理跨域的問題了。 使用 getImageData 能獲取到 canvas 上的像素信息,就可以根據刮刮卡上灰色的面積,決定擦除全部灰色的時機,更加靈活。

第二種方式,雖然不存在跨域的問題,但是,不能很好的根據刮刮卡上灰色的面積,控制最後擦除全部灰色的時機。

總結

文章中的效果主要是使用

globalCompositeOperation屬性取值為destination-out ,而取值為其他值的時候,同樣也是可以製作出各種效果的,大家也可以發揮自己的想像力,去試試其它值,也許有新發現呢。

更多程式相關知識,請造訪:

程式設計入門! !

以上是帶你了解canvas中的globalCompositeOperation屬性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

學習canvas框架 詳解常用的canvas框架 學習canvas框架 詳解常用的canvas框架 Jan 17, 2024 am 11:03 AM

探索Canvas框架:了解常用的Canvas框架有哪些,需要具體程式碼範例引言:Canvas是HTML5中提供的一個繪圖API,透過它我們可以實現豐富的圖形和動畫效果。為了提高繪圖的效率和便利性,許多開發者開發了不同的Canvas框架。本文將介紹一些常用的Canvas框架,並提供具體程式碼範例,以幫助讀者更深入地了解這些框架的使用方法。一、EaselJS框架Ea

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

探索canvas在遊戲開發中的強大作用及應用 探索canvas在遊戲開發中的強大作用及應用 Jan 17, 2024 am 11:00 AM

了解canvas在遊戲開發中的威力與應用概述:隨著網路科技的快速發展,網頁遊戲越來越受到廣大玩家的喜愛。而作為網頁遊戲開發中重要的一環,canvas技術在遊戲開發中逐漸嶄露頭角,展現出強大的威力與應用。本文將介紹canvas在遊戲開發中的潛力,並透過具體的程式碼範例來展示其應用。一、canvas技術簡介canvas是HTML5中新增的元素,它允許我們使用

中國教育界中Canvas的發展態勢與未來前景 中國教育界中Canvas的發展態勢與未來前景 Jan 17, 2024 am 10:22 AM

隨著科技的快速發展和資訊科技在教育領域的廣泛應用,Canvas作為一種全球領先的線上學習管理系統,正逐漸在中國教育界嶄露頭角。 Canvas的出現,為中國教育教學方式的改革提供了新的可能性。本文將探討Canvas在中國教育界的發展趨勢及前景。首先,Canvas在中國教育界的發展趨勢之一是深度融合。隨著雲端運算、大數據和人工智慧的快速發展,Canvas將越來越多地

See all articles