鸿蒙元服务实战-笑笑五子棋(2) 原创

万少skr
发布于 2025-1-5 08:32
浏览
0收藏

鸿蒙元服务实战-笑笑五子棋(2)

章节导读

本章节主要讲解如何创建元服务和使用 canvas 描绘图形

目标

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

上一章最后讲到了 笑笑五子棋 主要的技术栈如下:

  1. ArkTS API 12
  2. Canvas
  3. 元服务独有的 AtomicServiceTabs
  4. 卡片开发
  5. 元服务的创建
  6. 元服务的上架

那么本章节就开始实现这个案例。

AGC 平台上创建元服务

需要先在AGC平台上项目,然后再新建元服务。一个项目可以对应多个元服务。

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

DevEco Studio 创建元服务工程

AGC 平台上创建好了项目,我们可以在本地创建元服务。

  1. 新建元服务

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区


  1. 选择 笑笑五子棋

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

  1. 选择工程位置

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

  1. 元服务创建成功

    鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

Canvas 入门

Canvas提供画布组件,用于自定义绘制图形,开发者使用 CanvasRenderingContext2D 对象和 OffscreenCanvasRenderingContext2D

对象在 Canvas 组件上进行绘制,绘制对象可以是基础形状、文本、图片等。

基本使用

canvas 的基本使用分为 4 步:

  1. 设置是否抗锯齿抗锯齿(Anti - aliasing)是一种在数字图形处理中使用的技术,主要用于减少图像中因为像素有限而产生的锯齿状边缘的现象
  2. 创建画布上下文
  3. 渲染画布组件
  4. 在画布上描绘图案
@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)
  }
}
  1. 效果

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

canvas 常见用法

canvas 的核心思想是将想要的图形如,直线、圆圈、矩形等图形描绘到画布上。如果想要呈现出比较酷炫的效果,做法是:

  1. 描绘图形
  2. 擦除画布
  3. 计算数值-重新描绘图形
  4. 擦除画布
  5. 。。。

通过以上过程实现动画效果

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

canvas 的坐标系

在 canvas 中画图形都是基于坐标系来进行的。 左上角为起点。

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

描绘图形

canvas 中内置的常见的描绘图形的方法有以下:

  1. 直线
  2. 矩形
  3. 弧形
  4. 文本
  5. 图像

直线

描绘直线可以使用:

  1. 定起点 moveTo
  2. 定终点 lineTo
  3. 开始描绘 stroke
this.context.moveTo(10, 10);
this.context.lineTo(100, 100);
this.context.stroke();

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

矩形

可以使用直线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();

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

strokeRect 画矩形

// this.context.strokeRect(x, y, 宽度, 高度);
this.context.strokeRect(50, 50, 200, 150);

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

弧形

弧形可以使用 arcarcTo 来描绘

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

观察以下效果

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

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();

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

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。

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

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) 和圆弧的终点之间形成一个切线。

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

文本

  1. strokeText表示描边的图形
  2. fillText 表示填充的图形,还有其他fillfillRect等也表示填充。

strokeText

  this.context.font = '55px sans-serif'
  this.context.strokeText("Hello World!", 20, 60)

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

fillText

this.context.font = '55px sans-serif'
this.context.fillText("Hello World!", 20, 60)

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

图像

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 ImageBitmapPixelMap 图片资源,请参考 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%')
  }
}

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

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);

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

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);

鸿蒙元服务实战-笑笑五子棋(2)-鸿蒙开发者社区

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 的使用

如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
收藏
回复
举报
回复
    相关推荐