鸿蒙元服务实战-笑笑五子棋(2) 原创
鸿蒙元服务实战-笑笑五子棋(2)
章节导读
本章节主要讲解如何创建元服务和使用 canvas 描绘图形
目标
上一章最后讲到了 笑笑五子棋 主要的技术栈如下:
- ArkTS API 12
- Canvas
- 元服务独有的 AtomicServiceTabs
- 卡片开发
- 元服务的创建
- 元服务的上架
那么本章节就开始实现这个案例。
AGC 平台上创建元服务
需要先在AGC平台上项目,然后再新建元服务。一个项目可以对应多个元服务。
DevEco Studio 创建元服务工程
AGC 平台上创建好了项目,我们可以在本地创建元服务。
- 新建元服务
- 选择 笑笑五子棋
- 选择工程位置
-
元服务创建成功
Canvas 入门
Canvas提供画布组件,用于自定义绘制图形,开发者使用 CanvasRenderingContext2D 对象和 OffscreenCanvasRenderingContext2D
对象在 Canvas 组件上进行绘制,绘制对象可以是基础形状、文本、图片等。
基本使用
canvas 的基本使用分为 4 步:
- 设置是否抗锯齿抗锯齿(Anti - aliasing)是一种在数字图形处理中使用的技术,主要用于减少图像中因为像素有限而产生的锯齿状边缘的现象
- 创建画布上下文
- 渲染画布组件
- 在画布上描绘图案
@Entry
@Component
struct Index {
// 1 用来配置CanvasRenderingContext2D对象的参数,包括是否开启抗锯齿,true表明开启抗锯齿。
private settings: RenderingContextSettings = new RenderingContextSettings(true)
// 2 用来创建CanvasRenderingContext2D对象,通过在canvas中调用CanvasRenderingContext2D对象来绘制。
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
// 3 在canvas中调用CanvasRenderingContext2D对象。
Column(){
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() => {
// 4 可以在这里绘制内容。
this.context.strokeRect(50, 50, 200, 150);
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
- 效果
canvas 常见用法
canvas 的核心思想是将想要的图形如,直线、圆圈、矩形等图形描绘到画布上。如果想要呈现出比较酷炫的效果,做法是:
- 描绘图形
- 擦除画布
- 计算数值-重新描绘图形
- 擦除画布
- 。。。
通过以上过程实现动画效果
canvas 的坐标系
在 canvas 中画图形都是基于坐标系来进行的。 左上角为起点。
描绘图形
canvas 中内置的常见的描绘图形的方法有以下:
- 直线
- 矩形
- 弧形
- 文本
- 图像
- …
直线
描绘直线可以使用:
- 定起点
moveTo
- 定终点
lineTo
- 开始描绘
stroke
this.context.moveTo(10, 10);
this.context.lineTo(100, 100);
this.context.stroke();
矩形
可以使用直线lineTo
自己画成一个矩形。也可以直接使用 strokeRect
直接生成矩形
lineTo 画矩形
this.context.moveTo(10, 10);
this.context.lineTo(300, 10);
this.context.lineTo(300, 300);
this.context.lineTo(10, 300);
// 自动闭环
this.context.closePath();
// 开始描述 将路径的当前点移回到路径的起点,当前点到起点间画一条直线
this.context.stroke();
strokeRect 画矩形
// this.context.strokeRect(x, y, 宽度, 高度);
this.context.strokeRect(50, 50, 200, 150);
弧形
弧形可以使用 arc
和 arcTo
来描绘
arc
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean)
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
x | number | 是 | 弧线圆心的 x 坐标值。默认单位:vp。 |
y | number | 是 | 弧线圆心的 y 坐标值。默认单位:vp。 |
radius | number | 是 | 弧线的圆半径。默认单位:vp。 |
startAngle | number | 是 | 弧线的起始弧度。单位:弧度 |
endAngle | number | 是 | 弧线的终止弧度。单位:弧度 |
counterclockwise | boolean | 否 | 是否逆时针绘制圆弧。true:逆时针方向绘制椭圆。false:顺时针方向绘制椭圆。默认值:false。 |
这里需要注意的是 arc 使用的单位是弧度不是角度
一圈 = 360角度 = 2 * Math.PI
半圈 = 180角度 = Math.PI ≈ 3.14
观察以下效果
100,75 是圆心坐标
50 是半径
0 是开始的弧度
6.28 ≈ 2 * Math.PI = 一圈
arc 是从正右方向开始旋转的。
this.context.beginPath();
this.context.arc(100, 75, 50, 0, 3.14 / 2);
this.context.stroke();
arcTo
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number)
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
x1 | number | 是 | 第一个控制点的 x 坐标值。默认单位:vp。 |
y1 | number | 是 | 第一个控制点的 y 坐标值。默认单位:vp。 |
x2 | number | 是 | 第二个控制点的 x 坐标值。默认单位:vp。 |
y2 | number | 是 | 第二个控制点的 y 坐标值。默认单位:vp。 |
radius | number | 是 | 圆弧的圆半径值。默认单位:vp。 |
this.context.beginPath();
this.context.strokeStyle = "#000000";
this.context.lineWidth = 3;
this.context.moveTo(360, 20);
this.context.arcTo(360, 170, 110, 170, 150);
this.context.stroke();
辅助理解
想象一下,我们有一个起点(即当前路径的最后一个点),然后有三个更多的点:两个控制点 (x1, y1) 和 (x2, y2),以及由 radius
定义的一个圆心。arcTo
会创建一条从起点到第二个控制点 (x2, y2) 的圆弧,这条圆弧是位于以 radius
为半径的圆周上的一部
分。该圆弧会在起点和第一个控制点 (x1, y1) 之间形成一个切线,并且也会在第二个控制点 (x2, y2) 和圆弧的终点之间形成一个切线。
文本
- strokeText表示描边的图形
- fillText 表示填充的图形,还有其他fill,fillRect等也表示填充。
strokeText
this.context.font = '55px sans-serif'
this.context.strokeText("Hello World!", 20, 60)
fillText
this.context.font = '55px sans-serif'
this.context.fillText("Hello World!", 20, 60)
图像
drawImage可以把图像描绘到画布上,很多的在线图形合成效果都可以利用该功能实现
drawImage(image: ImageBitmap | PixelMap, dx: number, dy: number): void
drawImage(image: ImageBitmap | PixelMap, dx: number, dy: number, dw: number, dh: number): void
drawImage(image: ImageBitmap | PixelMap, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
image | ImageBitmap或PixelMap | 是 | 图片资源,请参考 ImageBitmap 或 PixelMap。 |
sx | number | 是 | 裁切源图像时距离源图像左上角的 x 坐标值。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
sy | number | 是 | 裁切源图像时距离源图像左上角的 y 坐标值。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
sw | number | 是 | 裁切源图像时需要裁切的宽度。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
sh | number | 是 | 裁切源图像时需要裁切的高度。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
dx | number | 是 | 绘制区域左上角在 x 轴的位置。默认单位:vp。 |
dy | number | 是 | 绘制区域左上角在 y 轴的位置。默认单位:vp。 |
dw | number | 是 | 绘制区域的宽度。当绘制区域的宽度和裁剪图像的宽度不一致时,将图像宽度拉伸或压缩为绘制区域的宽度。默认单位:vp。 |
dh | number | 是 | 绘制区域的高度。当绘制区域的高度和裁剪图像的高度不一致时,将图像高度拉伸或压缩为绘制区域的高度。默认单位:vp。 |
@Entry
@Component
struct Index {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private img: ImageBitmap = new ImageBitmap("/images/example.jpg")
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)
this.context.drawImage(this.img, 0, 150, 300, 100)
this.context.drawImage(this.img, 0, 0, 500, 500, 0, 300, 400, 200)
})
}
.width('100%')
.height('100%')
}
}
canvas 浅尝动态效果 1
const width = px2vp(display.getDefaultDisplaySync().availableWidth) * 0.9;
const height = width;
let x = 0;
let y = 0;
setInterval(() => {
this.context.strokeRect(x, y, 100, 100);
x++;
y++;
}, 20);
canvas 浅尝动态效果 2
const width = px2vp(display.getDefaultDisplaySync().availableWidth) * 0.9;
const height = width;
let x = 0;
let y = 0;
setInterval(() => {
// 清理画布
this.context.strokeRect(x, y, 100, 100);
x++;
y++;
}, 20);
canvas 属性 一览
名称 | 说明 |
---|---|
fillStyle | 设置绘制的填充色,支持多种类型及对应创建方式,有默认值。 |
lineWidth | 设置绘制线条的宽度,有默认值及取值限制。 |
strokeStyle | 设置线条的颜色,支持多种类型及对应创建方式,有默认值。 |
lineCap | 指定线端点的样式,有可选值及默认值。 |
lineJoin | 指定线段间相交的交点样式,有可选值及默认值。 |
miterLimit | 设置斜接面限制值,有默认值及取值限制。 |
font | 设置文本绘制中的字体样式,包含多种可选参数及默认值。 |
textAlign | 设置文本绘制中的文本对齐方式,有可选值及默认值。 |
textBaseline | 设置文本绘制中的水平对齐方式,有可选值及默认值。 |
globalAlpha | 设置透明度,有默认值。 |
lineDashOffset | 设置画布的虚线偏移量,有默认值。 |
globalCompositeOperation | 设置合成操作的方式,有可选值及默认值。 |
shadowBlur | 设置绘制阴影时的模糊级别,有默认值及取值限制。 |
shadowColor | 设置绘制阴影时的阴影颜色,有默认值。 |
shadowOffsetX | 设置绘制阴影时和原有对象的水平偏移值,有默认值。 |
shadowOffsetY | 设置绘制阴影时和原有对象的垂直偏移值,有默认值。 |
imageSmoothingEnabled | 设置绘制图片时是否进行图像平滑度调整,有默认值。 |
height | 表示组件高度,有默认单位。 |
width | 表示组件宽度,有默认单位。 |
imageSmoothingQuality | 设置图像平滑度,有默认值。 |
direction | 设置绘制文字时使用的文字方向,有默认值。 |
filter | 设置图像的滤镜,支持多种滤镜效果,有默认值。 |
canvas | 获取和 CanvasRenderingContext2D 关联的 Canvas 组件的 FrameNode 实例,<br />可监听可见状态,默认值为 null。 |
canvas 方法 一览
名称 | 说明 |
---|---|
fillRect | 推测用于进行图形填充相关操作(通常是填充矩形区域) |
strokeRect | 推测用于绘制矩形边框相关操作(通常是绘制矩形的轮廓) |
clearRect | 推测用于清除指定矩形区域的内容 |
fillText | 推测用于对文本进行填充操作(比如设置文本填充颜色等相关样式填充) |
strokeText | 推测用于绘制文本的轮廓相关操作 |
measureText | 推测用于测量文本相关的尺寸等属性 |
stroke | 一般用于绘制图形的轮廓、线条等(按常规语义理解) |
beginPath | 通常用于开始定义一个新的路径,后续可基于此路径进行图形绘制等操作 |
moveTo | 常用来将画笔移动到指定坐标位置,作为绘制路径的起始点等操作 |
lineTo | 一般用于从当前画笔位置绘制直线到指定坐标位置,构建路径内容 |
closePath | 通常用于闭合当前正在绘制的路径,使路径形成封闭图形 |
createPattern | 可能用于创建某种图案(比如重复平铺的图案等)用于绘制等 |
bezierCurveTo | 大概率用于绘制贝塞尔曲线,通过控制点来定义曲线形状 |
quadraticCurveTo | 推测用于绘制二次贝塞尔曲线,指定控制点来确定曲线走向 |
arc | 一般用于绘制圆弧,通过圆心、半径、起始角度、结束角度等参数来定义 |
arcTo | 常用来绘制与两条切线相切的圆弧,按给定条件确定圆弧形状 |
ellipse | 用于绘制椭圆图形,需指定相关参数如圆心坐标、长半轴、短半轴等 |
rect | 可用于绘制矩形,指定矩形的左上角坐标、宽度、高度等参数 |
fill | 用于对已绘制的图形或者指定区域进行填充操作 |
clip | 可能用于设置裁剪区域,后续绘制内容只在裁剪区域内显示 |
reset12+ | 从名称看可能是在特定版本(12+)中用于重置某些状态或设置的操作 |
saveLayer12+ | 在特定版本(12+)里可能用于保存图层相关状态等操作 |
restoreLayer12+ | 在特定版本(12+)里对应于之前保存图层状态进行恢复的操作 |
resetTransform | 推测用于重置图形变换相关的设置(比如旋转、缩放等变换) |
rotate | 用于将图形进行旋转操作,需指定旋转角度等参数 |
scale | 用于对图形进行缩放操作,指定横向和纵向的缩放比例 |
transform | 一般用于对图形进行多种变换(如平移、旋转、缩放等组合变换)的设置 |
setTransform | 可能用于设置图形的变换矩阵,来确定图形的变换情况 |
getTransform | 推测用于获取当前图形的变换相关信息(比如变换矩阵等) |
translate | 用于将图形进行平移操作,指定在横、纵坐标方向平移的距离 |
drawImage | 通常用于在画布上绘制图像,指定图像源及绘制位置等参数 |
createImageData | 可能用于创建图像数据对象(比如像素数据等相关内容) |
getPixelMap | 推测用于获取像素映射相关的数据(比如图像像素的分布等情况) |
setPixelMap | 大概是用于设置像素映射相关数据,改变图像像素表现等 |
getImageData | 一般用于获取图像的像素数据等具体信息内容 |
putImageData | 通常是将获取到的图像数据(如像素数据)重新应用到画布等位置 |
setLineDash | 可能用于设置线条的虚线样式,指定虚线的长度、间隔等参数 |
getLineDash | 推测用于获取当前线条所设置的虚线样式相关参数 |
transferFromImageBitmap | 从名称看可能是与从图像位图进行数据转移相关操作 |
toDataURL | 通常用于将画布等内容转换为可以表示图像数据的 URL 格式 |
restore | 一般用于恢复之前保存的某些状态(如画布状态等) |
save | 常用来保存当前画布等相关的状态,以便后续恢复使用 |
createLinearGradient | 用于创建线性渐变对象,可用于图形的渐变填充等操作 |
createRadialGradient | 用于创建径向渐变对象,定义从中心向外扩散的渐变效果 |
createConicGradient | 用于创建圆锥渐变对象,实现类似圆锥形状的渐变效果 |
总结
这篇文章主要是介绍了元服务的创建和基本 canvas 的使用
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。