第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

繪制狀態(tài)存儲

1. 前言

canvas 中設(shè)置屬性多數(shù)都是全局使用的,我們在操作時難免會遇到某個屬性被修改后,當(dāng)再次使用到這個屬性時必須是默認(rèn)值的情況,或者我們繪制多個矩形,這些矩形的填充顏色和陰影有一定規(guī)律,比如填充顏色為 紅、黃、藍(lán)、黃、紅這樣的順序,陰影也是有對應(yīng)順序,我們應(yīng)該怎么做呢?本小節(jié)我們就來學(xué)習(xí)如何保存某個繪制狀態(tài)和快速地將繪制狀態(tài)恢復(fù)到上一個階段。

2. 存儲繪制狀態(tài)

我們先看一個不使用存儲繪制狀態(tài)的案例,這個案例中,我們需要繪制5個矩形,其中第一個和第五個矩形相同,第二個和第四個矩形相同。

實例演示
預(yù)覽 復(fù)制
復(fù)制成功!
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>慕課網(wǎng)Wiki</title>
    <style>
        #imooc{
            border:1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="imooc">您的瀏覽器不支持 HTML5 canvas 標(biāo)簽</canvas>
    <script>
		const canvas = document.getElementById('imooc');
		canvas.width=360;
		canvas.height=130;
		const ctx = canvas.getContext('2d');
		
		// 繪制第一個矩形
		ctx.fillStyle="red"
		ctx.shadowBlur=2;
		ctx.shadowOffsetX=4;
		ctx.shadowOffsetY=4;
		ctx.shadowColor="#ccc"
		ctx.fillRect(40,40, 40,40)
		
		// 繪制第二個矩形
		ctx.fillStyle="yellow"
		ctx.shadowBlur=3;
		ctx.shadowOffsetX=8;
		ctx.shadowOffsetY=8;
		ctx.shadowColor="#456795"
		ctx.fillRect(100,40, 40,40)
		
		
		// 繪制第三個矩形
		ctx.fillStyle="blue"
		ctx.shadowBlur=5;
		ctx.shadowOffsetX=5;
		ctx.shadowOffsetY=5;
		ctx.shadowColor="#222"
		ctx.fillRect(160,40, 40,40)
		
		// 繪制第四個矩形
		ctx.fillStyle="yellow"
		ctx.shadowBlur=3;
		ctx.shadowOffsetX=8;
		ctx.shadowOffsetY=8;
		ctx.shadowColor="#456795"
		ctx.fillRect(220,40, 40,40)
		
		// 繪制第五個矩形
		ctx.fillStyle="red"
		ctx.shadowBlur=2;
		ctx.shadowOffsetX=4;
		ctx.shadowOffsetY=4;
		ctx.shadowColor="#ccc"
		ctx.fillRect(280,40, 40,40)
		
	</script>
<body>
</html>
運行案例 點擊 "運行案例" 可查看在線運行效果

運行結(jié)果:

上面案例中,可以看到,繪制第四個正方形的時候,把所有屬性又寫了一遍,但是這個屬性和我們繪制第二個正方形的屬性一樣,第五個正方形和第一個正方形的屬性一樣,這樣我們不僅浪費時間還增加了代碼維護(hù)成本,維護(hù)成本主要指:假如我們要修改紅色的正方形為其他顏色,我們就得修改兩處代碼。

今天我們就用存儲繪制狀態(tài)的方法來優(yōu)化一下上面代碼,還是上面那個案例,我們換一種寫法。

實例演示
預(yù)覽 復(fù)制
復(fù)制成功!
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>慕課網(wǎng)Wiki</title>
    <style>
        #imooc{
            border:1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="imooc">您的瀏覽器不支持 HTML5 canvas 標(biāo)簽</canvas>
    <script>
		const canvas = document.getElementById('imooc');
		canvas.width=360;
		canvas.height=130;
		const ctx = canvas.getContext('2d');
		
		// 繪制第一個矩形
		ctx.fillStyle="red"
		ctx.shadowBlur=2;
		ctx.shadowOffsetX=4;
		ctx.shadowOffsetY=4;
		ctx.shadowColor="#ccc"
		ctx.save();    // 這里把當(dāng)前畫布的屬性做了一個標(biāo)記,我們稱為:標(biāo)記一
		ctx.fillRect(40,40, 40,40)
		
		// 繪制第二個矩形
		ctx.fillStyle="yellow"
		ctx.shadowBlur=3;
		ctx.shadowOffsetX=8;
		ctx.shadowOffsetY=8;
		ctx.shadowColor="#456795"
		ctx.save();    // 這里把當(dāng)前畫布的屬性做了第二個標(biāo)記,我們稱為:標(biāo)記二
		ctx.fillRect(100,40, 40,40)
		
		// 繪制第三個矩形
		ctx.fillStyle="blue"
		ctx.shadowBlur=5;
		ctx.shadowOffsetX=5;
		ctx.shadowOffsetY=5;
		ctx.shadowColor="#222"
		ctx.fillRect(160,40, 40,40)
		
		// 繪制第四個矩形
		ctx.restore()  // 這里我們讀取了最新的一個標(biāo)記,也就是讀區(qū)了標(biāo)記二的狀態(tài),標(biāo)記二被讀取后就消失了。
		ctx.fillRect(220,40, 40,40)
		
		// 繪制第五個矩形
		ctx.restore(); // 這里我們讀取了最新的一個標(biāo)記,也就是讀區(qū)了標(biāo)記一的狀態(tài),因為標(biāo)記二已經(jīng)消失了
		ctx.fillRect(280,40, 40,40)
		
	</script>
<body>
</html>
運行案例 點擊 "運行案例" 可查看在線運行效果

運行結(jié)果:

我們可以看到,運行結(jié)果是一樣的,我們把主要代碼拆分講解一下。

  1. 設(shè)置繪制矩形的相關(guān)屬性,并調(diào)用 save 方法保存一個繪制狀態(tài)。

    	ctx.fillStyle="red"
    	ctx.shadowBlur=2;
    	ctx.shadowOffsetX=4;
    	ctx.shadowOffsetY=4;
    	ctx.shadowColor="#ccc"
    	ctx.save();    // 這里把當(dāng)前畫布的屬性做了一個標(biāo)記,我們稱為:標(biāo)記一
    	ctx.fillRect(40,40, 40,40)
    
    
  2. 設(shè)置第二個矩形的相關(guān)屬性,并調(diào)用 save 方法保存一個繪制狀態(tài),這個狀態(tài)會堆放到上一個狀態(tài)的上面,該狀態(tài)的存儲符合“?!钡奶匦裕合冗M(jìn)后出,也就是最先放進(jìn)去的最后才被拿走。

    我們看一個形象的圖片,小孩的玩具。

    最下面的大圈是最先放進(jìn)去的,再取出時它是最后一個被拿出來的。

    	ctx.fillStyle="yellow"
    	ctx.shadowBlur=3;
    	ctx.shadowOffsetX=8;
    	ctx.shadowOffsetY=8;
    	ctx.shadowColor="#456795"
    	ctx.save();    // 這里把當(dāng)前畫布的屬性做了第二個標(biāo)記,我們稱為:標(biāo)記二
    	ctx.fillRect(100,40, 40,40)
    
    
  3. 繪制第四個矩形,我們在繪制前先調(diào)用 ctx.restore 方法取出一個狀態(tài),取出的狀態(tài)會應(yīng)用到當(dāng)前畫布上。當(dāng)前存儲的所有狀態(tài)中,最上面的是標(biāo)簽二,也就是第二個矩形的狀態(tài),所以這里取出來的就是第二個矩形的狀態(tài)屬性。

    	ctx.restore()  // 取出狀態(tài)
    	ctx.fillRect(220,40, 40,40)
    
  4. 繪制第五個矩形,同樣調(diào)用 ctx.restore 方法取出一個狀態(tài),當(dāng)前存儲的狀態(tài)中只有標(biāo)簽一,也就是第一個矩形的狀態(tài),所以這里取出來的就是第一個矩形的狀態(tài)屬性。

    	ctx.restore(); // 取出狀態(tài)
    	ctx.fillRect(280,40, 40,40)
    

特別注意 當(dāng)存儲的狀態(tài)被取完以后,再去取一個狀態(tài),此時會出問題。解決辦法就是:讀取狀態(tài) restore 的次數(shù)只能小于等于存儲 save 的次數(shù)。

3. 方法整理

本小節(jié)我們學(xué)習(xí)了 save 方法和 restore 方法,它們的主要作用是存儲某一個階段的屬性狀態(tài),后面可以快速恢復(fù)存儲的狀態(tài)。

3.1 存儲狀態(tài) save

save 說明

  • save 方法主要目的是存儲 canvas 當(dāng)前全部狀態(tài),此方法可以多次執(zhí)行,每次執(zhí)行都會存儲一次當(dāng)前狀態(tài)。

語法:

ctx.save();

變量說明:

沒有參數(shù)。

3.2 存儲狀態(tài) restore

restore 說明

  • restore 方法主要是用于取出存儲在 canvas 中的最新狀態(tài),此方法可以多次執(zhí)行,但是不能超過已存儲狀態(tài)的次數(shù)。

語法:

ctx.restore();

變量說明:

沒有參數(shù)。

4. 總結(jié)

本小節(jié)我們主要學(xué)習(xí)了利用 saverestore 存儲和拿取畫布狀態(tài)的方法,存儲狀態(tài)的目的是后面可以快速恢復(fù)到上一個繪制狀態(tài)。本小節(jié)我們只是簡單體會了存儲和拿取的過程,后面小節(jié)我們學(xué)習(xí)了旋轉(zhuǎn)變形的操作,會頻繁地用到這個操作。