動態

詳情 返回 返回

鴻蒙元服務實戰-笑笑五子棋(2) - 動態 詳情

鴻蒙元服務實戰-笑笑五子棋(2)

章節導讀

本章節主要講解如何創建元服務和使用 canvas 描繪圖形

目標

img

上一章最後講到了 笑笑五子棋 主要的技術棧如下:

  1. ArkTS API 12
  2. Canvas
  3. 元服務獨有的 AtomicServiceTabs
  4. 卡片開發
  5. 元服務的創建
  6. 元服務的上架

那麼本章節就開始實現這個案例。

AGC 平台上創建元服務

需要先在AGC平台上項目,然後再新建元服務。_一個項目可以對應多個元服務。_

image-20250104215412454

DevEco Studio 創建元服務工程

AGC 平台上創建好了項目,我們可以在本地創建元服務。

  1. 新建元服務

image-20250104215538468


  1. 選擇 笑笑五子棋

image-20250104215654355

  1. 選擇工程位置

image-20250104215718600

  1. 元服務創建成功

    image-20250104220153486

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. 效果

image-20250104222001043

canvas 常見用法

canvas 的核心思想是將想要的圖形如,直線、圓圈、矩形等圖形描繪到畫布上。如果想要呈現出比較酷炫的效果,做法是:

  1. 描繪圖形
  2. 擦除畫布
  3. 計算數值-重新描繪圖形
  4. 擦除畫布
  5. 。。。

通過以上過程實現動畫效果

image-20250104223622772

canvas 的座標系

在 canvas 中畫圖形都是基於座標系來進行的。 左上角為起點。

image-20250104224722034

描繪圖形

canvas 中內置的常見的描繪圖形的方法有以下:

  1. 直線
  2. 矩形
  3. 弧形
  4. 文本
  5. 圖像
  6. ...

直線

描繪直線可以使用:

  1. 定起點 moveTo
  2. 定終點 lineTo
  3. 開始描繪 stroke
this.context.moveTo(10, 10);
this.context.lineTo(100, 100);
this.context.stroke();

image-20250104224216771

矩形

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

image-20250104225516822

strokeRect 畫矩形

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

image-20250104225643875

弧形

弧形可以使用 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

觀察以下效果

image-20250104230514600

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

image-20250104230945457

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。

image-20250104235451185

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) 和圓弧的終點之間形成一個切線。

image-20250104234845265

文本

  1. strokeText表示描邊的圖形
  2. fillText 表示填充的圖形,還有其他fillfillRect等也表示填充。

strokeText

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

image-20250104235533508

fillText

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

image-20250104235642059

圖像

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%')
  }
}

image-20250105000141244

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

PixPin_2025-01-05_00-07-08

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

PixPin_2025-01-05_00-08-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 實例,
可監聽可見狀態,默認值為 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 的使用

如果你興趣想要了解更多的鴻蒙應用開發細節和最新資訊,歡迎在評論區留言或者私信或者看我個人信息,可以加入技術交流羣。

user avatar huanjinliu 頭像 HarmonyOS5 頭像 hongmengbaixiaosheng 頭像 cason6810 頭像
點贊 4 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.