鸿蒙元服务实战-笑笑五子棋(3)
接上篇。上一篇主要讲解了元服务的创建和 canvas 的一些基本使用,直线、矩形、弧形、文本、图像等。canvas 本身还有很多其他
的功能。这里继续围绕 canvas 进行讲解。
createPattern
createPattern(image: ImageBitmap, repetition: string | null): CanvasPattern | null
通过指定图像和重复方式创建图片填充的模板。
参数名 | 类型 | 必填 | 说明 | |
---|---|---|---|---|
image | ImageBitmap | 是 | 图源对象,具体参考 ImageBitmap 对象。 | |
repetition | string \ | null | 是 | 设置图像重复的方式:'repeat':沿 x 轴和 y 轴重复绘制图像;'repeat-x':沿 x 轴重复绘制图像;'repeat-y':沿 y 轴重复绘制图像;'no-repeat':不重复绘制图像;'clamp':在原始边界外绘制时,超出部分使用边缘的颜色绘制;'mirror':沿 x 轴和 y 轴重复翻转绘制图像。 |
提前准备好图片
基本使用
- 基于图片创建填充模版
- 设置到 canvas 的 fillStyle 中
- 进行描绘
@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 基于图片创建填充模版
2.
let pattern = this.context.createPattern(this.img, 'no-repeat') // 不平铺
if (pattern) {
// 2 设置到canvas的fillStyle中
this.context.fillStyle = pattern
}
// 3 进行描绘
this.context.fillRect(0, 0, 400, 400)
})
}
.width('100%')
.height('100%')
}
}
效果:
repetition:repeat
设置平铺
let pattern = this.context.createPattern(this.img, "repeat");
效果
clamp
在原始边界外绘制时,超出部分使用边缘的颜色绘制;
let pattern = this.context.createPattern(this.img, "clamp");
mirror
沿 x 轴和 y 轴重复翻转绘制图像。
let pattern = this.context.createPattern(this.img, "mirror");
quadraticCurveTo
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void
创建二次贝赛尔曲线的路径。
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
cpx | number | 是 | 贝塞尔参数的 x 坐标值。默认单位:vp。 |
cpy | number | 是 | 贝塞尔参数的 y 坐标值。默认单位:vp。 |
x | number | 是 | 路径结束时的 x 坐标值。默认单位:vp。 |
y | number | 是 | 路径结束时的 y 坐标值。默认单位: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
创建三次贝赛尔曲线的路径。
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
cp1x | number | 是 | 第一个贝塞尔参数的 x 坐标值。默认单位:vp。 |
cp1y | number | 是 | 第一个贝塞尔参数的 y 坐标值。默认单位:vp。 |
cp2x | number | 是 | 第二个贝塞尔参数的 x 坐标值。默认单位:vp。 |
cp2y | number | 是 | 第二个贝塞尔参数的 y 坐标值。默认单位:vp。 |
x | number | 是 | 路径结束时的 x 坐标值。默认单位:vp。 |
y | number | 是 | 路径结束时的 y 坐标值。默认单位:vp。 |
示例代码
this.context.beginPath()
this.context.moveTo(10, 10)
this.context.bezierCurveTo(20, 100, 200, 100, 200, 20)
this.context.stroke()
效果
辅助理解
ImageData
ImageData对象可以存储 canvas 渲染的像素数据。也就是说 ImageData 可以让我们使用 canvas 对画布中的每一个像素进行操作。提
供了强大的控制能力。
实例属性
Uint8ClampedArray
描述了一个一维数组,包含以 RGBA 顺序的数据,数据使用0
至255
(包含)的整数表示。无符号长整型(
unsigned long
),使用像素描述 ImageData 的实际高度。无符号长整型(
unsigned long
),使用像素描述 ImageData 的实际宽度。
这里通过 canvas 的[getImageData]()方法快速获取 ImageData 数据。然后通过putImageData把处理好的内容重新描绘到画图上。
@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 其他效果
反转效果:
- 原理:通过将每个像素的 RGB 值取反来实现反转效果。
- 实现方式:使用
getImageData
获取图像数据,然后遍历每个像素,将每个像素的 RGB 值取反,再使用putImageData
将修改后的数据绘制回 Canvas。
黑白效果:
- 原理:将每个像素的 RGB 值转换为灰度值,使图像变为黑白。
- 实现方式:使用
getImageData
获取图像数据,然后遍历每个像素,将每个像素的 RGB 值转换为灰度值(R、G、B 三个分量取平均值),再使用putImageData
将修改后的数据绘制回 Canvas。
亮度效果:
- 原理:调整每个像素的亮度值,使图像变亮或变暗。
- 实现方式:使用
getImageData
获取图像数据,然后遍历每个像素,调整每个像素的亮度值,再使用putImageData
将修改后的数据绘制回 Canvas。
复古效果:
- 原理:通过调整每个像素的色调、饱和度和亮度,使图像呈现复古效果。
- 实现方式:使用
getImageData
获取图像数据,然后遍历每个像素,调整每个像素的色调、饱和度和亮度,再使用putImageData
将修改后的数据绘制回 Canvas。
红色、绿色、蓝色效果:
- 原理:增加或减少每个像素的红色、绿色、蓝色分量的值,使图像呈现相应颜色的效果。
- 实现方式:使用
getImageData
获取图像数据,然后遍历每个像素,增加或减少每个像素的红色、绿色、蓝色分量的值,再使用putImageData
将修改后的数据绘制回 Canvas。
透明效果:
- 原理:调整每个像素的透明度值,使图像呈现透明效果。
- 实现方式:使用
getImageData
获取图像数据,然后遍历每个像素,调整每个像素的透明度值,再使用putImageData
将修改后的数据绘制回 Canvas。
马赛克效果:
- 原理:将图像分割为小块,每个小块的像素值设置为该小块内像素的平均值,从而实现马赛克效果。
- 实现方式:使用
getImageData
获取图像数据,然后将图像分割为小块,计算每个小块内像素的平均值,再将该小块内所有像素的值设置为该平均值,最后使用putImageData
将修改后的数据绘制回 Canvas。
马赛克效果
- 由于实际操作过程中,上述马赛克效果处理性能比较底下,这里用来一个取巧的效果来实现。就是先用 canvas 将画面画小,然后再将画面缩放来实现一个模糊效果,间接实现马赛克效果
渐变滤镜效果:
- 原理:通过在图像上应用渐变效果,使图像呈现渐变色的效果。
- 实现方式:使用
createLinearGradient
或createRadialGradient
创建渐变对象,然后使用渐变对象作为填充样式,绘制图像到 Canvas 上。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。