• 鸿蒙画布组件使用介绍


    一、前言

    DevEco Studio版本:4.0.0.600

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

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

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

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

    参考链接:OpenHarmony CanvasRenderingContext2D

    二、实现效果

    三、具体实现逻辑

    1、初始化

    1. private settings: RenderingContextSettings = new RenderingContextSettings(true)
    2. private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
    3. private img: ImageBitmap = new ImageBitmap("images/startIcon.png")
    4. build() {
    5. Stack({ alignContent: Alignment.Center }) {
    6. Canvas(this.context)
    7. .padding({ top: 76 })
    8. .width('100%')
    9. .height('100%')
    10. .onReady(() => {
    11. this.drawCanvas()
    12. })
    13. }
    14. .width('100%')
    15. .height('100%')
    16. }
    17. //画布逻辑
    18. private drawCanvas(): void {
    19. this.context.fillStyle = '#0080DC' //画笔填充颜色
    20. this.context.strokeStyle = '#0080DC' //画笔线条颜色
    21. this.context.font = '22px' //字体大小
    22. }

    2、画文字

    1. //画文字
    2. this.context.fillText("Hello World!", 10, 10)

    3、画矩形

    1. //画矩形
    2. this.context.strokeRect(10, 30, 100, 100)

    4、画线条

    1. //画线
    2. this.context.beginPath()
    3. this.context.moveTo(10, 150)
    4. this.context.lineTo(180, 200)
    5. this.context.stroke()

    5、画圆形

    1. //画圆形
    2. this.context.beginPath()
    3. this.context.arc(60, 250, 50, 0, 2 * Math.PI)
    4. this.context.stroke()

    6、画椭圆形

    1. //画椭圆形
    2. this.context.beginPath()
    3. this.context.ellipse(100, 360, 50, 100, Math.PI * 0.5, 0, Math.PI * 2)
    4. this.context.stroke()

    7、画三角形

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

    1. //画三角形
    2. this.context.beginPath()
    3. this.context.moveTo(10, 500)
    4. this.context.lineTo(60, 420)
    5. this.context.lineTo(120, 500)
    6. this.context.closePath()
    7. this.context.stroke()

     

    8、画扇形

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

    1. //画扇形
    2. this.context.beginPath()
    3. this.context.arc(110, 620, 100, Math.PI, 1.75 * Math.PI)
    4. this.context.moveTo(10, 620)
    5. this.context.lineTo(110, 620)
    6. this.context.lineTo(180.71, 549.29)
    7. this.context.stroke()

    9、画图片

    1. //画图片
    2. this.context.drawImage(this.img, 0, 0, 144, 144, 150, 0, 144, 144)

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

    原理演示动画:

    效果:

    代码实现:

    1. import display from '@ohos.display'
    2. @Entry
    3. @Component
    4. struct Index {
    5. private settings: RenderingContextSettings = new RenderingContextSettings(true)
    6. private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
    7. private mDisplayWidth: number
    8. private mDisplayHeight: number
    9. aboutToAppear() {
    10. this.getSize()
    11. }
    12. // 获取设备宽高计算表盘大小
    13. async getSize() {
    14. let mDisplay = await display.getDefaultDisplay()
    15. this.mDisplayWidth = mDisplay.width
    16. this.mDisplayHeight = mDisplay.height
    17. }
    18. build() {
    19. Stack({ alignContent: Alignment.Center }) {
    20. Canvas(this.context)
    21. .padding({ top: 76 })
    22. .width('100%')
    23. .height('100%')
    24. .onReady(() => {
    25. this.drawCanvas()
    26. })
    27. .onTouch((event) => this.touchEvent(event))
    28. }
    29. .width('100%')
    30. .height('100%')
    31. }
    32. private drawCanvas(): void {
    33. this.context.clearRect(0, 0, this.mDisplayWidth, this.mDisplayHeight)
    34. this.context.strokeStyle = '#0080DC' //画笔线条颜色
    35. this.context.lineWidth = 3
    36. this.context.font = '22px' //字体大小
    37. //画第一个圆
    38. this.context.beginPath()
    39. this.context.arc(20, 200, 5, 0, 2 * Math.PI)
    40. this.context.stroke()
    41. //画第二个圆
    42. this.context.beginPath()
    43. this.context.arc(305, 200, 5, 0, 2 * Math.PI)
    44. this.context.stroke()
    45. //画贝塞尔曲线
    46. this.context.beginPath()
    47. this.context.moveTo(20, 195)
    48. this.context.quadraticCurveTo(this.eventX, this.eventY, 300, 200)
    49. this.context.stroke()
    50. }
    51. @State eventX: number = 0
    52. @State eventY: number = 500
    53. touchEvent(event: TouchEvent) {
    54. switch (event.type) {
    55. case TouchType.Down: // 手指按下
    56. case TouchType.Move: // 手指移动
    57. this.eventX = event.touches[0].x
    58. this.eventY = event.touches[0].y
    59. this.drawCanvas()
    60. break
    61. }
    62. }
    63. }

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

    原理演示动画:

    效果:

    代码实现:

    1. import display from '@ohos.display'
    2. @Entry
    3. @Component
    4. struct Index {
    5. private settings: RenderingContextSettings = new RenderingContextSettings(true)
    6. private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
    7. private mDisplayWidth: number
    8. private mDisplayHeight: number
    9. @State isFirst: boolean = true
    10. aboutToAppear() {
    11. this.getSize()
    12. }
    13. // 获取设备宽高计算表盘大小
    14. async getSize() {
    15. let mDisplay = await display.getDefaultDisplay()
    16. this.mDisplayWidth = mDisplay.width
    17. this.mDisplayHeight = mDisplay.height
    18. }
    19. build() {
    20. Stack({ alignContent: Alignment.Center }) {
    21. Canvas(this.context)
    22. .padding({ top: 76 })
    23. .width('100%')
    24. .height('100%')
    25. .onReady(() => {
    26. this.drawCanvas()
    27. })
    28. .onTouch((event) => this.touchEvent(event))
    29. Button(`点击切换,当前${this.isFirst ? '第一点' : '第二点'}`)
    30. .onClick(() => {
    31. this.isFirst = !this.isFirst
    32. })
    33. }
    34. .alignContent(Alignment.TopStart)
    35. .width('100%')
    36. .height('100%')
    37. }
    38. private drawCanvas(): void {
    39. this.context.clearRect(0, 0, this.mDisplayWidth, this.mDisplayHeight)
    40. this.context.strokeStyle = '#0080DC' //画笔线条颜色
    41. this.context.lineWidth = 3
    42. this.context.font = '22px' //字体大小
    43. //画第一个圆
    44. this.context.beginPath()
    45. this.context.arc(20, 200, 5, 0, 2 * Math.PI)
    46. this.context.stroke()
    47. //画第二个圆
    48. this.context.beginPath()
    49. this.context.arc(405, 200, 5, 0, 2 * Math.PI)
    50. this.context.stroke()
    51. //画贝塞尔曲线
    52. this.context.beginPath()
    53. this.context.moveTo(20, 195)
    54. this.context.bezierCurveTo(this.eventFirstX, this.eventFirstX, this.eventSecondX, this.eventSecondY, 400, 200)
    55. this.context.stroke()
    56. this.context.stroke()
    57. }
    58. @State eventFirstX: number = 120
    59. @State eventFirstY: number = 50
    60. @State eventSecondX: number = 200
    61. @State eventSecondY: number = 500
    62. touchEvent(event: TouchEvent) {
    63. switch (event.type) {
    64. case TouchType.Down: // 手指按下
    65. case TouchType.Move: // 手指移动
    66. if (this.isFirst) {
    67. this.eventFirstX = event.touches[0].x
    68. this.eventFirstY = event.touches[0].y
    69. } else {
    70. this.eventSecondX = event.touches[0].x
    71. this.eventSecondY = event.touches[0].y
    72. }
    73. this.drawCanvas()
    74. break
    75. }
    76. }
    77. }

  • 相关阅读:
    GUI编程--PyQt5--QWidget2
    Redis跳表详解(附面试题)
    Visual Studio Code的安装和使用
    C++ 正则表达式使用
    感恩的力量!美洲杯魔幻提前预告 阿根廷 ——早读(逆天打工人爬取热门微信文章解读)
    C# 常用功能整合-3
    StyleGAN 生成 AI 虚拟人脸,再也不怕侵犯肖像权
    mixup--学习笔记
    二叉排序树的删除操作的实现(思路分析)
    2023年全国大学生数学建模B题
  • 原文地址:https://blog.csdn.net/Abner_Crazy/article/details/137045457