鸿蒙元服务实战-笑笑五子棋(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)
这里需要注意的是 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)
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
@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 属性 一览
canvas 方法 一览
总结
这篇文章主要是介绍了元服务的创建和基本 canvas 的使用
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。
评论