鴻蒙元服務(wù)實戰(zhàn)-笑笑五子棋(3)
接上篇。上一篇主要講解了元服務(wù)的創(chuàng)建和 canvas 的一些基本使用,直線、矩形、弧形、文本、圖像等。canvas 本身還有很多其他
的功能。這里繼續(xù)圍繞 canvas 進(jìn)行講解。
createPattern
createPattern(image: ImageBitmap, repetition: string | null): CanvasPattern | null
通過指定圖像和重復(fù)方式創(chuàng)建圖片填充的模板。
| 參數(shù)名 | 類型 | 必填 | 說明 |
|---|---|---|---|
| image | ImageBitmap | 是 | 圖源對象,具體參考 ImageBitmap 對象。 |
| repetition | string | null | 是 |
提前準(zhǔn)備好圖片

基本使用
- 基于圖片創(chuàng)建填充模版
- 設(shè)置到 canvas 的 fillStyle 中
- 進(jìn)行描繪
@Entry
@Component
struct Index {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private img: ImageBitmap = new ImageBitmap("/images/2.png")
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#ffff00')
.onReady(() = > {
// 1 基于圖片創(chuàng)建填充模版
2.
let pattern = this.context.createPattern(this.img, 'no-repeat') // 不平鋪
if (pattern) {
// 2 設(shè)置到canvas的fillStyle中
this.context.fillStyle = pattern
}
// 3 進(jìn)行描繪
this.context.fillRect(0, 0, 400, 400)
})
}
.width('100%')
.height('100%')
}
}
效果 :

repetition:repeat
設(shè)置平鋪
let pattern = this.context.createPattern(this.img, "repeat");
效果

clamp
在原始邊界外繪制時,超出部分使用邊緣的顏色繪制;
let pattern = this.context.createPattern(this.img, "clamp");

mirror
沿 x 軸和 y 軸重復(fù)翻轉(zhuǎn)繪制圖像。
let pattern = this.context.createPattern(this.img, "mirror");

quadraticCurveTo
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void
創(chuàng)建二次貝賽爾曲線的路徑。
| 參數(shù)名 | 類型 | 必填 | 說明 |
|---|---|---|---|
| cpx | number | 是 | 貝塞爾參數(shù)的 x 坐標(biāo)值。默認(rèn)單位:vp。 |
| cpy | number | 是 | 貝塞爾參數(shù)的 y 坐標(biāo)值。默認(rèn)單位:vp。 |
| x | number | 是 | 路徑結(jié)束時的 x 坐標(biāo)值。默認(rèn)單位:vp。 |
| y | number | 是 | 路徑結(jié)束時的 y 坐標(biāo)值。默認(rèn)單位:vp。 |
示例代碼
this.context.beginPath();
this.context.moveTo(20, 20);
this.context.quadraticCurveTo(100, 100, 200, 20);
this.context.stroke();
效果

輔助理解


bezierCurveTo
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void
創(chuàng)建三次貝賽爾曲線的路徑。
| 參數(shù)名 | 類型 | 必填 | 說明 |
|---|---|---|---|
| cp1x | number | 是 | 第一個貝塞爾參數(shù)的 x 坐標(biāo)值。默認(rèn)單位:vp。 |
| cp1y | number | 是 | 第一個貝塞爾參數(shù)的 y 坐標(biāo)值。默認(rèn)單位:vp。 |
| cp2x | number | 是 | 第二個貝塞爾參數(shù)的 x 坐標(biāo)值。默認(rèn)單位:vp。 |
| cp2y | number | 是 | 第二個貝塞爾參數(shù)的 y 坐標(biāo)值。默認(rèn)單位:vp。 |
| x | number | 是 | 路徑結(jié)束時的 x 坐標(biāo)值。默認(rèn)單位:vp。 |
| y | number | 是 | 路徑結(jié)束時的 y 坐標(biāo)值。默認(rèn)單位:vp。 |
示例代碼
this.context.beginPath()
this.context.moveTo(10, 10)
this.context.bezierCurveTo(20, 100, 200, 100, 200, 20)
this.context.stroke()
效果

輔助理解


ImageData
ImageData對象可以存儲 canvas 渲染的像素數(shù)據(jù)。也就是說 ImageData 可以讓我們使用 canvas 對畫布中的每一個像素進(jìn)行操作。提
供了強(qiáng)大的控制能力。
實例屬性
ImageData.data只讀Uint8ClampedArray描述了一個一維數(shù)組,包含以 RGBA 順序的數(shù)據(jù),數(shù)據(jù)使用0至255(包含)的整數(shù)表示。ImageData.height只讀
無符號長整型(unsigned long),使用像素描述 ImageData 的實際高度。ImageData.width只讀
無符號長整型(unsigned long),使用像素描述 ImageData 的實際寬度。
這里通過 canvas 的getImageData方法快速獲取 ImageData 數(shù)據(jù)。然后通過putImageData把處理好的內(nèi)容重新描繪到畫圖上。
@Entry
@Component
struct Index {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private img: ImageBitmap = new ImageBitmap("/images/2.png")
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#ffff00')
.onReady(() = > {
this.context.drawImage(this.img, 0, 0, 130, 130)
// 獲取了 ImageData 示例
let imagedata = this.context.getImageData(50, 50, 130, 130)
// 又重新描繪到canvas上
this.context.putImageData(imagedata, 150, 150)
})
}
.width('100%')
.height('100%')
}
}
效果

ImageData 反色
this.context.drawImage(this.img, 0, 0, 130, 130);
// 獲取了 ImageData 示例
let imagedata = this.context.getImageData(50, 50, 130, 130);
// console.log("xxx,", JSON.stringify(imagedata.data))
Object.keys(imagedata.data).forEach((k) = > {
// 反色
imagedata.data[k] = 255 - imagedata.data[k];
});
// 又重新描繪到canvas上
this.context.putImageData(imagedata, 150, 150);

ImageData 其他效果
反轉(zhuǎn)效果:
- 原理:通過將每個像素的 RGB 值取反來實現(xiàn)反轉(zhuǎn)效果。
- 實現(xiàn)方式:使用
getImageData獲取圖像數(shù)據(jù),然后遍歷每個像素,將每個像素的 RGB 值取反,再使用putImageData將修改后的數(shù)據(jù)繪制回 Canvas。
黑白效果:
- 原理:將每個像素的 RGB 值轉(zhuǎn)換為灰度值,使圖像變?yōu)楹诎住?/li>
- 實現(xiàn)方式:使用
getImageData獲取圖像數(shù)據(jù),然后遍歷每個像素,將每個像素的 RGB 值轉(zhuǎn)換為灰度值(R、G、B 三個分量取平均值),再使用putImageData將修改后的數(shù)據(jù)繪制回 Canvas。
亮度效果:
- 原理:調(diào)整每個像素的亮度值,使圖像變亮或變暗。
- 實現(xiàn)方式:使用
getImageData獲取圖像數(shù)據(jù),然后遍歷每個像素,調(diào)整每個像素的亮度值,再使用putImageData將修改后的數(shù)據(jù)繪制回 Canvas。
復(fù)古效果:
- 原理:通過調(diào)整每個像素的色調(diào)、飽和度和亮度,使圖像呈現(xiàn)復(fù)古效果。
- 實現(xiàn)方式:使用
getImageData獲取圖像數(shù)據(jù),然后遍歷每個像素,調(diào)整每個像素的色調(diào)、飽和度和亮度,再使用putImageData將修改后的數(shù)據(jù)繪制回 Canvas。
紅色、綠色、藍(lán)色效果:
- 原理:增加或減少每個像素的紅色、綠色、藍(lán)色分量的值,使圖像呈現(xiàn)相應(yīng)顏色的效果。
- 實現(xiàn)方式:使用
getImageData獲取圖像數(shù)據(jù),然后遍歷每個像素,增加或減少每個像素的紅色、綠色、藍(lán)色分量的值,再使用putImageData將修改后的數(shù)據(jù)繪制回 Canvas。
透明效果:
- 原理:調(diào)整每個像素的透明度值,使圖像呈現(xiàn)透明效果。
- 實現(xiàn)方式:使用
getImageData獲取圖像數(shù)據(jù),然后遍歷每個像素,調(diào)整每個像素的透明度值,再使用putImageData將修改后的數(shù)據(jù)繪制回 Canvas。
馬賽克效果:
- 原理:將圖像分割為小塊,每個小塊的像素值設(shè)置為該小塊內(nèi)像素的平均值,從而實現(xiàn)馬賽克效果。
- 實現(xiàn)方式:使用
getImageData獲取圖像數(shù)據(jù),然后將圖像分割為小塊,計算每個小塊內(nèi)像素的平均值,再將該小塊內(nèi)所有像素的值設(shè)置為該平均值,最后使用putImageData將修改后的數(shù)據(jù)繪制回 Canvas。
馬賽克效果
- 由于實際操作過程中,上述馬賽克效果處理性能比較底下,這里用來一個取巧的效果來實現(xiàn)。就是先用 canvas 將畫面畫小,然后再將畫面縮放來實現(xiàn)一個模糊效果,間接實現(xiàn)馬賽克效果
漸變?yōu)V鏡效果:
- 原理:通過在圖像上應(yīng)用漸變效果,使圖像呈現(xiàn)漸變色的效果。
- 實現(xiàn)方式:使用
createLinearGradient或createRadialGradient創(chuàng)建漸變對象,然后使用漸變對象作為填充樣式,繪制圖像到 Canvas 上。
參考鏈接
- [數(shù)學(xué)曲線之一:貝塞爾曲線](https://zhuanlan.zhihu.com/p/711975272)
- [神奇 canvas 帶你實現(xiàn)魔法攝像頭](https://juejin.cn/post/7264125562393788473#heading-8)
- [ImageData](https://developer.mozilla.org/zh-CN/docs/Web/API/ImageData)
審核編輯 黃宇
-
Canvas
+關(guān)注
關(guān)注
0文章
21瀏覽量
11386 -
鴻蒙
+關(guān)注
關(guān)注
60文章
2866瀏覽量
45402
發(fā)布評論請先 登錄
labview五子棋程序
基于labview的五子棋設(shè)計
用Verilog寫的一個五子棋
Delphi教程_使用DrawGrid控件制作五子棋
基于LabVIEW的五子棋博弈算法
鴻蒙元服務(wù)實戰(zhàn)-笑笑五子棋(1)

鴻蒙元服務(wù)實戰(zhàn)-笑笑五子棋(3)
評論