鸿蒙画布组件使用介绍

一、前言

DevEco Studio版本:4.0.0.600

前些天写了一篇鸿蒙自定义控件实现罗盘数字时钟效果 的文章,有同学私信说能不能介绍鸿蒙中的画布组件,下面文章介绍下鸿蒙中的Canvas画布、CanvasRenderingContext2D绘制组件,实现绘制文本、矩形、线条、圆形、椭圆、三角形、扇形、图片等。

Canvas:提供画布组件,用于自定义绘制图形。

**CanvasRenderingContext2D:**使用RenderingContext在Canvas组件上进行绘制,绘制对象可以是矩形、文本、图片等,相当于画笔

**RenderingContextSettings:**用来配置CanvasRenderingContext2D对象的参数,包括是否开启抗锯齿

参考链接:OpenHarmony CanvasRenderingContext2D

二、实现效果

三、具体实现逻辑

1、初始化

复制代码
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private img: ImageBitmap = new ImageBitmap("images/startIcon.png")

build() {
   Stack({ alignContent: Alignment.Center }) {
      Canvas(this.context)
         .padding({ top: 76 })
         .width('100%')
         .height('100%')
         .onReady(() => {
            this.drawCanvas()
         })
   }
   .width('100%')
   .height('100%')
}


//画布逻辑
private drawCanvas(): void {
   this.context.fillStyle = '#0080DC' //画笔填充颜色
   this.context.strokeStyle = '#0080DC' //画笔线条颜色
   this.context.font = '22px' //字体大小
}

2、画文字

复制代码
//画文字
this.context.fillText("Hello World!", 10, 10)

3、画矩形

复制代码
//画矩形
this.context.strokeRect(10, 30, 100, 100)

4、画线条

复制代码
//画线
this.context.beginPath()
this.context.moveTo(10, 150)
this.context.lineTo(180, 200)
this.context.stroke()

5、画圆形

复制代码
//画圆形
this.context.beginPath()
this.context.arc(60, 250, 50, 0, 2 * Math.PI)
this.context.stroke()

6、画椭圆形

复制代码
//画椭圆形
this.context.beginPath()
this.context.ellipse(100, 360, 50, 100, Math.PI * 0.5, 0, Math.PI * 2)
this.context.stroke()

7、画三角形

先画两条线,然后通过closePath()方法实现闭环,依次达到画三角形效果

复制代码
//画三角形
this.context.beginPath()
this.context.moveTo(10, 500)
this.context.lineTo(60, 420)
this.context.lineTo(120, 500)
this.context.closePath()
this.context.stroke()

8、画扇形

先画弧线,在画两条基于弧线起点和终点的线,依次来达到画扇形的效果

复制代码
//画扇形
this.context.beginPath()
this.context.arc(110, 620, 100, Math.PI, 1.75 * Math.PI)
this.context.moveTo(10, 620)
this.context.lineTo(110, 620)
this.context.lineTo(180.71, 549.29)
this.context.stroke()

9、画图片

复制代码
//画图片
this.context.drawImage(this.img, 0, 0, 144, 144, 150, 0, 144, 144)

10、画二阶贝赛尔曲线的路径

原理演示动画:

效果:

代码实现:

复制代码
import display from '@ohos.display'

@Entry
@Component
struct Index {
   private settings: RenderingContextSettings = new RenderingContextSettings(true)
   private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
   private mDisplayWidth: number
   private mDisplayHeight: number

   aboutToAppear() {
      this.getSize()
   }

   // 获取设备宽高计算表盘大小
   async getSize() {
      let mDisplay = await display.getDefaultDisplay()
      this.mDisplayWidth = mDisplay.width
      this.mDisplayHeight = mDisplay.height
   }

   build() {
      Stack({ alignContent: Alignment.Center }) {
         Canvas(this.context)
            .padding({ top: 76 })
            .width('100%')
            .height('100%')
            .onReady(() => {
               this.drawCanvas()
            })
            .onTouch((event) => this.touchEvent(event))
      }
      .width('100%')
      .height('100%')
   }

   private drawCanvas(): void {
      this.context.clearRect(0, 0, this.mDisplayWidth, this.mDisplayHeight)
      this.context.strokeStyle = '#0080DC' //画笔线条颜色
      this.context.lineWidth = 3
      this.context.font = '22px' //字体大小
      //画第一个圆
      this.context.beginPath()
      this.context.arc(20, 200, 5, 0, 2 * Math.PI)
      this.context.stroke()
      //画第二个圆
      this.context.beginPath()
      this.context.arc(305, 200, 5, 0, 2 * Math.PI)
      this.context.stroke()
      //画贝塞尔曲线
      this.context.beginPath()
      this.context.moveTo(20, 195)
      this.context.quadraticCurveTo(this.eventX, this.eventY, 300, 200)
      this.context.stroke()
   }

   @State eventX: number = 0
   @State eventY: number = 500

   touchEvent(event: TouchEvent) {
      switch (event.type) {
         case TouchType.Down: // 手指按下
         case TouchType.Move: // 手指移动
            this.eventX = event.touches[0].x
            this.eventY = event.touches[0].y
            this.drawCanvas()
            break
      }
   }
}

11、画三阶贝赛尔曲线的路径

原理演示动画:

效果:

代码实现:

复制代码
import display from '@ohos.display'

@Entry
@Component
struct Index {
   private settings: RenderingContextSettings = new RenderingContextSettings(true)
   private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
   private mDisplayWidth: number
   private mDisplayHeight: number
   @State isFirst: boolean = true

   aboutToAppear() {
      this.getSize()
   }

   // 获取设备宽高计算表盘大小
   async getSize() {
      let mDisplay = await display.getDefaultDisplay()
      this.mDisplayWidth = mDisplay.width
      this.mDisplayHeight = mDisplay.height
   }

   build() {
      Stack({ alignContent: Alignment.Center }) {
         Canvas(this.context)
            .padding({ top: 76 })
            .width('100%')
            .height('100%')
            .onReady(() => {
               this.drawCanvas()
            })
            .onTouch((event) => this.touchEvent(event))

         Button(`点击切换,当前${this.isFirst ? '第一点' : '第二点'}`)
            .onClick(() => {
               this.isFirst = !this.isFirst
            })
      }
      .alignContent(Alignment.TopStart)
      .width('100%')
      .height('100%')
   }

   private drawCanvas(): void {
      this.context.clearRect(0, 0, this.mDisplayWidth, this.mDisplayHeight)
      this.context.strokeStyle = '#0080DC' //画笔线条颜色
      this.context.lineWidth = 3
      this.context.font = '22px' //字体大小
      //画第一个圆
      this.context.beginPath()
      this.context.arc(20, 200, 5, 0, 2 * Math.PI)
      this.context.stroke()
      //画第二个圆
      this.context.beginPath()
      this.context.arc(405, 200, 5, 0, 2 * Math.PI)
      this.context.stroke()
      //画贝塞尔曲线
      this.context.beginPath()
      this.context.moveTo(20, 195)
      this.context.bezierCurveTo(this.eventFirstX, this.eventFirstX, this.eventSecondX, this.eventSecondY, 400, 200)
      this.context.stroke()
      this.context.stroke()
   }

   @State eventFirstX: number = 120
   @State eventFirstY: number = 50
   @State eventSecondX: number = 200
   @State eventSecondY: number = 500

   touchEvent(event: TouchEvent) {
      switch (event.type) {
         case TouchType.Down: // 手指按下
         case TouchType.Move: // 手指移动
            if (this.isFirst) {
               this.eventFirstX = event.touches[0].x
               this.eventFirstY = event.touches[0].y
            } else {
               this.eventSecondX = event.touches[0].x
               this.eventSecondY = event.touches[0].y
            }
            this.drawCanvas()
            break
      }
   }
}
相关推荐
廖松洋(Alina)9 分钟前
04极速划词页面实现-鸿蒙PC端Electron开发
华为·electron·开源·harmonyos·鸿蒙
轻口味16 分钟前
HarmonyOS 6.1 全栈实战录 - 07 极速连接:Remote Communication Kit (RCP) 实战与认证挑战深度解析
华为·harmonyos
想你依然心痛37 分钟前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与Face AR & Body AR的“灵犀康养“——PC端沉浸式AR智能康复训练系统
华为·ar·harmonyos·悬浮导航·沉浸光感
廖松洋(Alina)1 小时前
03主入口页面与导航结构-鸿蒙PC端Electron开发
前端·javascript·华为·electron·开源·harmonyos·鸿蒙
廖松洋(Alina)1 小时前
09词根分解与水印展示-鸿蒙PC端Electron开发
前端·javascript·华为·electron·开源·harmonyos·鸿蒙
音视频牛哥1 小时前
大牛直播SDK(SmartMediaKit)鸿蒙NEXT同屏RTMP推流与轻量级RTSP服务集成实践指南
华为·harmonyos·大牛直播sdk·鸿蒙next无纸化同屏·鸿蒙next rtmp推流·鸿蒙next rtsp服务器·鸿蒙next无纸化会议
xmdy58661 小时前
Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day4 停车订单生成+多状态管理+在线缴费+我的订单+会员中心+个人中心完善
flutter·开源·harmonyos
xmdy58661 小时前
Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day8 进阶美化与真机调优篇
flutter·华为·harmonyos
Swift社区1 小时前
鸿蒙 PC vs Web:谁才是未来应用形态?
前端·华为·harmonyos
忧云1 小时前
KaihongOS 5.0|免费鸿蒙 X86 桌面系统|普通电脑直装|旧电脑复活 + 安卓应用兼容
harmonyos·鸿蒙系统·华为鸿蒙