鸿蒙元服务实战-笑笑五子棋(2)
章节导读
本章节主要讲解如何创建元服务和使用 canvas 描绘图形
目标
上一章最后讲到了 笑笑五子棋 主要的技术栈如下:
- ArkTS API 12 
- Canvas 
- 元服务独有的 AtomicServiceTabs 
- 卡片开发 
- 元服务的创建 
- 元服务的上架 
那么本章节就开始实现这个案例。
AGC 平台上创建元服务
需要先在AGC平台上项目,然后再新建元服务。一个项目可以对应多个元服务。
DevEco Studio 创建元服务工程
AGC 平台上创建好了项目,我们可以在本地创建元服务。
- 新建元服务 
- 选择 笑笑五子棋 
- 选择工程位置 
- 元服务创建成功 
 
Canvas 入门
Canvas提供画布组件,用于自定义绘制图形,开发者使用 CanvasRenderingContext2D 对象和 OffscreenCanvasRenderingContext2D
对象在 Canvas 组件上进行绘制,绘制对象可以是基础形状、文本、图片等。
基本使用
canvas 的基本使用分为 4 步:
- 设置是否抗锯齿抗锯齿(Anti - aliasing)是一种在数字图形处理中使用的技术,主要用于减少图像中因为像素有限而产生的锯齿状边缘的现象 
- 创建画布上下文 
- 渲染画布组件 
- 在画布上描绘图案 
 @Entry@Componentstruct 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@Componentstruct 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 的使用
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。
评论