一奕枢、繪制文字
【1】font字體屬性
canvas 里的font 屬性和css 的font 屬性是一樣的娄昆,它可以設(shè)置文本的粗細(xì)、字號(hào)验辞、字體等
- css 設(shè)置字體:p{ font: bold 15px 微軟雅黑; }
- canvas 設(shè)置字體:ctx.font = 'bold 15px 微軟雅黑'
【2】textAlign水平對(duì)齊
textAlign 設(shè)置或返回文本內(nèi)容的當(dāng)前對(duì)齊方式
- start: 默認(rèn), 文本在指定的位置開(kāi)始
- end: 文本在指定的位置結(jié)束
- center: 文本的中心被放置在指定的位置
- left: 文本左對(duì)齊
- right: 文本右對(duì)齊
【3】textBaseline垂直對(duì)齊
textBaseline 設(shè)置或返回在繪制文本時(shí)使用的當(dāng)前文本基線
- alphabetic:默認(rèn)稿黄,文本基線是普通的字母基線
- top:文本基線是 em 方框的頂端
- hanging:文本基線是懸掛基線
- middle:文本基線是 em 方框的正中
- ideographic: 文本基線是 em 基線
- bottom:文本基線是 em 方框的底端
【4】文本繪制方法
填充文字: fillText(text, x, y, maxWidth)
描邊文字: strokeText(text, x, y, maxWidth)
解釋:
text:填充的文字
x y:坐標(biāo)
maxWidth:文字最大寬度喊衫,該值小于文字寬度會(huì)自動(dòng)縮小填充文字
【5】獲取文字寬度方法
獲取文字寬度:ctx.measureText(text)
【6】案例
<body>
<canvas id="canvas"></canvas>
<script>
// 創(chuàng)建canvas
const canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
// 文字屬性
ctx.font = 'bold 200px Arial';
// 投影
ctx.shadowColor = 'rgba(0,0,0,0.6)';
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 4;
// 實(shí)體文字
ctx.fillStyle = '#b76251';
ctx.fillText('canvas', 50, 150);
// 實(shí)體描邊文字
ctx.strokeStyle = '#f0d5bc';
ctx.lineWidth = 9;
ctx.strokeText('canvas', 50, 150);
// 虛線描邊
ctx.strokeStyle = '#000';
ctx.lineWidth = 1;
ctx.setLineDash([5, 3]);
ctx.strokeText('canvas', 50, 150);
</script>
</body>
二跌造、繪制圖片
【1】繪制圖像的基本方式(繪圖+位移)
語(yǔ)法:ctx.drawImage(img, x族购,y)
參數(shù)說(shuō)明:
img:是繪制圖片的dom對(duì)象
x y :圖片向右和向下位移坐標(biāo)
【2】繪圖+位移+寬高
語(yǔ)法:ctx.drawImage(img壳贪,x,y寝杖,width违施,height)
參數(shù)說(shuō)明:
img:是繪制圖片的dom對(duì)象
x y :圖片向右和向下位移坐標(biāo)
width:繪制圖片的寬度
height:繪制圖片的高度
【3】繪圖+位移+寬高+裁剪
語(yǔ)法:ctx.drawImage(img,sx瑟幕,sy磕蒲,swidth,sheight只盹,x辣往,y,width殖卑,height)
參數(shù)說(shuō)明:
img:是繪制圖片的dom對(duì)象
sx sy: 裁剪的左上角坐標(biāo)
swidth:裁剪圖片的高度
sheight:裁剪的高度
x y :圖片向右和向下位移坐標(biāo)
width:繪制圖片的寬度
height:繪制圖片的高度
【4】JavaScript建立圖像源的方式
// 第一種
var img = document.getElementById('imgId');
// 第二種
let img = new Image(); //這個(gè)就是img標(biāo)簽的dom對(duì)象
img.src = '/images/test.gif';
img.alt = '文本信息';
img.onload = function() {
//圖片加載完成后站削,執(zhí)行此方法
};
【5】案例
<body>
<canvas id="canvas"></canvas>
<script>
// 創(chuàng)建畫(huà)布
const canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
// 創(chuàng)建圖像源
const img = new Image();
img.src = './images/person.png';
img.onload = function () {
const { width, height } = img;
// 繪圖+移動(dòng) drawImage(img, x, y)
// ctx.drawImage(img, 0, 0);
// 繪圖+移動(dòng)+寬高 drawImage(img, x, y, width, height)
ctx.drawImage(img, 0, 0, width / 5, height / 5); //偏移到x軸為0 y軸為0的位置展示, 圖片寬高=原圖寬高/5
// 繪圖+裁剪+移動(dòng)+寬高 drawImage(img, sx, sy, swidth, sheight, x, y, width, height)
ctx.drawImage(
img,
0, 0, width / 2, height / 2, // 從左邊 0,0 開(kāi)始裁剪孵稽, 裁剪原圖寬度的一半许起,高度的一半
200, 0, width / 5, height / 5 // 偏移到x軸200y軸0的位置展示, 圖片寬高=原圖寬高/5
);
};
</script>
</body>
三菩鲜、像素操作
【1】imageData是什么园细?
ImageData 是圖片的數(shù)據(jù)化,是一個(gè)對(duì)象接校,它具備以下幾個(gè)屬性:
data:Uint8ClampedArray[r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a]
width:整數(shù)猛频,ImageData的寬度
heidth:整數(shù),ImageData的高度
Uint8ClampedArray 翻譯過(guò)來(lái)是 8位無(wú)符號(hào)整型固定數(shù)組馅笙,每四個(gè)數(shù)組元素代表了一個(gè)像素點(diǎn)的rgba信息伦乔,每個(gè)元素?cái)?shù)值取值范圍是[0,255]董习。若小于0烈和,則為0,大于255皿淋,則為255招刹。若為小數(shù)恬试,則取整,取整的方法是銀行家舍入疯暑。
【2】獲取imageData對(duì)象
方法:ctx.getImageData(x, y, width, height)
作用: 用來(lái)獲取canvas畫(huà)布上指定矩形區(qū)域的像素?cái)?shù)據(jù)
解釋:
xy: 矩形的左頂點(diǎn)橫縱坐標(biāo)
width: 矩形的寬度
height: 矩形的高度
【3】imageData可以做什么训柴?
我可以通過(guò)不同的算法,對(duì)ImageData 中的像素進(jìn)行不同的處理妇拯。比如調(diào)整圖片的色調(diào)幻馁,檢測(cè)圖像邊緣,實(shí)現(xiàn)藝術(shù)效果越锈,馬賽克仗嗦,人臉識(shí)別……
【4】案例
遍歷圖片像素,通過(guò)灰度算法對(duì)圖片像素做處理使圖片變成灰色調(diào)
<body>
<canvas id="canvas"></canvas>
<script>
// 創(chuàng)建畫(huà)布
const canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
// js創(chuàng)建圖片源
const img = new Image();
img.src = 'https://img-blog.csdnimg.cn/20210407160120758.png'
img.setAttribute('crossOrigin', '');
img.onload = draw;
function draw() {
// 圖像尺寸
const { width, height } = img;
// 在canvas 中繪制圖像
ctx.drawImage(img, 10, 10, 150, 200);
// 從canvas 中獲取圖像的ImageData
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
// 像素遍歷
for (let i = 0; i < data.length; i += 4) {
const [r, g, b] = [
data[i],
data[i + 1],
data[i + 2],
]
// 將圖片變灰甘凭,灰度算法公式: 0.299*r+0.587*g+0.114*b
const lm = 0.299 * r + 0.587 * g + 0.114 * b;
data[i] = lm;
data[i + 1] = lm;
data[i + 2] = lm;
}
// 在canvas 中顯示ImageData
ctx.putImageData(imgData, 0, 0);
}
</script>
</body>
四稀拐、變換
【1】縮放scale()
作用:scale()方法縮放當(dāng)前繪圖,更大或更小
語(yǔ)法:ctx.scale(scalewidth丹弱,scaleheight)
scalewidth : 縮放當(dāng)前繪圖的寬度 (1=100%德撬, 0.5=50%,2=200%躲胳,依次類推)
scaleheight : 縮放當(dāng)前繪圖的高度 (1=100%蜓洪,0.5=50%,2=200%泛鸟,依次類推)
注意:縮放的是整個(gè)畫(huà)布蝠咆,縮放后,繼續(xù)繪制的圖形會(huì)被放大或縮小
【2】位移translate()
語(yǔ)法:ctx.translate(x, y)
x: 添加到水平坐標(biāo)(x)上的值
y: 添加到垂直坐標(biāo)(y)上的值
注意:發(fā)生位移后北滥,相當(dāng)于把畫(huà)布的 0,0 坐標(biāo) 更換到新的 x,y 的位置刚操,所有繪制的新元素都被影響。位移畫(huà)布一般配合縮放和旋轉(zhuǎn)等再芋。
【3】旋轉(zhuǎn)rotate()
作用:方法旋轉(zhuǎn)當(dāng)前的繪圖
語(yǔ)法:context.rotate(angle)
angle:弧度(PI)
注意:參數(shù)是弧度(PI)菊霜,如需將角度轉(zhuǎn)換為弧度,請(qǐng)使用 degrees*Math.PI/180 公式進(jìn)行計(jì)算
【4】繪制環(huán)境保存和還原
ctx.save() 保存當(dāng)前環(huán)境的狀態(tài)济赎,可以把當(dāng)前繪制環(huán)境進(jìn)行保存到緩存中
ctx.restore() 恢復(fù)之前保存過(guò)的路徑狀態(tài)和屬性鉴逞,獲取最近緩存的 ctx,一般配合位移畫(huà)布使用
一般在我們繪制具備同一種樣式的圖形時(shí)司训,都會(huì)用save() restore() 將其包裹起來(lái)构捡。這是為了避免當(dāng)前的圖形樣式影響以后的圖形樣式。
【5】案例
<body>
<canvas id="canvas"></canvas>
<script>
// 創(chuàng)建畫(huà)布
const canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
// 縮放: scale(x,y)
ctx.save()
ctx.scale(2, 2); // 放大到200%
ctx.fillRect(0, 0, 100, 100);
ctx.restore()
// 移動(dòng): translate(x,y)
ctx.save()
ctx.translate(250, 0); // 移動(dòng)到x軸為250和y軸都為0的位置
ctx.fillRect(0, 0, 100, 100);
ctx.restore()
// 旋轉(zhuǎn): rotate(angle)
ctx.save()
ctx.rotate(Math.PI / 4);
ctx.fillRect(300, 0, 100, 100);
ctx.restore()
</script>
</body>
文章每周持續(xù)更新壳猜,可以微信搜索「 前端大集錦 」第一時(shí)間閱讀勾徽,回復(fù)【視頻】【書(shū)籍】領(lǐng)取200G視頻資料和30本PDF書(shū)籍資料