前言

昨天华为mate60提早发售,网上撒播,麒麟9000s,“4G改””,“突破列强科技封闭”等字眼撒播在各大社交平台,我对着那些mate60相关文章左看右看,上看下看,竟从鳞次栉比的文字中看出四个字——“遥遥领先

其实原因是在沸点看见这么一个表情包,然后就用HarmonyOS ArkUI 的 Canvas画了一个神光棒(我没有说华为是国产之光啊,叠甲)。不跑偏了,咱们今天经过画这个神光棒来了解下HarmonyOS ArkUI 的 Canvas

HarmonyOS ArkUI Canvas(你相信光吗?)


一、Canvas是什么?

Canvas是 ArkUI 供给的画布组件,用于自定义制作图形。它运用类似于HTML5 Canvas的方式进行制作,能够完成高效、灵活的自定义UI界面。Canvas能够完成在画布上自在制作图形,包括线条、矩形、圆形、文本、图片等,并且能够经过操控制作次序和渲染次序来完成图层管理和遮盖作用。

参数:

参数名 参数类型 必填 默许值 参数描绘
context CanvasRenderingContext2D 见CanvasRenderingContext2D对象。

二、画神光棒

想要画一个神光棒,咱们要先将它拆解,看看它由什么组成,然后咱们就得到了如下公式:

HarmonyOS ArkUI Canvas(你相信光吗?)

神光棒=圆+左面的多边形+右边的多边形+衔接部分+棒身+底座神光棒 = 圆+左面的多边形+右边的多边形+衔接部分+棒身+底座

得到公式后咱们一步一步将其画出来,在开端运用Canvas组件之前,咱们需求先初始化CanvasRenderingContext2D

private settings: RenderingContextSettings = new RenderingContextSettings(true)
 private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

然后用这个context初始化

      Canvas(this.context)
        .width('100%')
        .height('100%')
        .onReady(() => {
          })

接下来的一切绘画工作都将在onReady办法中进行,context自带宽高特点,代表了控件的宽高以方便咱们制作

 		  let width = this.context.width
          let height = this.context.height

1.制作神光棒左右侧

代码如下(示例):

		  this.context.lineWidth = 2
		  this.context.beginPath()
          this.context.moveTo(width/2, height/4)
          this.context.lineTo(width/4, height/8)
          this.context.lineTo(width/4, height/3)
          this.context.arcTo(width/4, height/2, width/2, height/2, 90)
          this.context.closePath()
          this.context.stroke()

解说

  1. beginPath():beginPath() 是 canvas 的办法之一,它的作用是创立一个新途径,用于制作图形。新途径创立后,之前制作的途径和样式将被清空。在开端制作新的途径之前,咱们一般需求调用此办法来创立一个新的途径对象。

  2. moveTo():的moveTo办法是用于将画笔移动到指定的坐标点。具体语法如下: –public void moveTo(float x, float y) 其间,x和y别离表明坐标点的横纵坐标。

  3. lineTo(): lineTo办法用于在指定坐标处开端制作一条直线。其语法与moveTo相同

  4. arcTo(): arcTo() 是 Canvas API 中的途径制作办法之一。它用于制作一段弧线,该弧线的起点和结尾是已知的,可是中心的弧度巨细和轨道需求经过操控点来操控。

arcTo() 办法有四个参数,前两个参数是操控点坐标,中心两个参数是结尾坐标。它的语法如下:

context.arcTo(x1, y1, x2, y2, radius)

在制作途径时,咱们一般先用 moveTo() 办法来设置途径的开始点,然后用 arcTo() 办法来制作一段弧线,最终用 lineTo() 或许其它途径制作办法来弥补途径的其它部分。

运用 arcTo() 办法需求留意以下几点:

  • 途径的开始点不能和弧线的起点重合;
  • 操控点的坐标和结尾的坐标有必要在同一直线上;
  • 操控点和结尾的距离有必要大于弧线的半径,不然将无法制作出弧线;
  • 如果要制作出多段弧线,每段弧线的起点和上一段弧线的结尾有必要重合,不然将会构成断点。
  1. closePath():用于将当时笔画的起点和结尾衔接起来,构成一个封闭途径。当调用 closePath() 后,下一次的制作操作就会从途径的起点开端,而不是继续上一次途径的结尾。途径的起点默许是最终一个 moveTo() 办法所设置的点。如果当时途径没有进行 moveTo() 操作,则起点自动设置为 (0, 0)。在 closePath() 之后,你能够经过 fill() 或 stroke() 办法来填充或描边途径。如果当时途径没有构成封闭途径(即起点和结尾未衔接),则 closePath() 办法不会产生任何作用。

  2. stroke():用于设置描边样式的办法。它能够用于设置图形的描边颜色、宽度和样式。

     context.stroke()
    

stroke() 办法一般在制作完图形的途径后调用。调用该办法将当时描边样式应用于途径,并在画布上制作描边途径。

在调用该办法之前,您能够经过以下办法设置描边样式:

  • context.strokeStyle :设置描边颜色。能够是一个字符串值,如“red”或“#FF0000”,也能够是 CanvasGradient 或 CanvasPattern 对象。
  • context.lineWidth :设置描边线宽度,单位为像素。
  • context.lineCap :设置线条的端点样式,能够是 butt(默许)、round 或 square。
  • context.lineJoin :设置线条的衔接点样式,能够是 miter(默许)、round 或 bevel。
  • context.miterLimit :设置斜角的约束比例,只有当 lineJoin 为 miter 时才有用。

作用如下:

HarmonyOS ArkUI Canvas(你相信光吗?)

同理,咱们只需求改换一下位置坐标,就能将右侧画出来

          this.context.beginPath()
          this.context.moveTo(width/2, height/4)
          this.context.lineTo(width/4*3, height/8)
          this.context.lineTo(width/4*3, height/3)
          this.context.arcTo(width/4*3, height/2, width/2, height/2, 90)
          // this.context.closePath()
          this.context.stroke()

作用入下

HarmonyOS ArkUI Canvas(你相信光吗?)

2.中心圆形

代码如下(示例):

 		  this.context.beginPath()
          this.context.arc(width/2, height/3, 40, 0, 360)
          // this.context.stroke()
          var grad = this.context.createRadialGradient(200,200,50, 200,200,200)
          grad.addColorStop(0.0, '#ffd7d556')
          grad.addColorStop(1.0, '#ffcdc555')
          grad.addColorStop(0.5, '#ffffff')
          this.context.fillStyle = grad
          this.context.fill()

解说:

  1. arc(): arc 办法是用来制作圆弧的。

该办法的语法如下:

public void arc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

参数阐明:

  • left:圆弧地点矩形的左面界坐标;
  • top:圆弧地点矩形的上鸿沟坐标;
  • ight:圆弧地点矩形的右鸿沟坐标;
  • bottom:圆弧地点矩形的下鸿沟坐标;
  • startAngle:圆弧开始视点,以度数表明;
  • sweepAngle:圆弧扫描视点,以度数表明;
  • useCenter:是否制作扇形,默许为 false,表明制作圆弧;
  • paint:制作圆弧所运用的画笔。

运用 arc 办法能够画出各种圆弧,如扇形、半圆等。同时,经过设置 startAngle 和 sweepAngle 能够制作出不同的圆弧形状。

  1. createRadialGradient 用于创立一个放射性突变的函数,也便是完成在给定的两个圆之间进行颜色突变的功能。具体来说,该办法接纳6个参数:
  • centerX: 突变圆的中心点横坐标。
  • centerY: 突变圆的中心点纵坐标。
  • radius: 突变圆的半径。
  • centerX2: 第二个突变圆的中心点横坐标。
  • centerY2: 第二个突变圆的中心点纵坐标。
  • radius2: 第二个突变圆的半径。

该办法会返回一个突变对象,能够在canvas上运用该对象进行制作。

作用如下:

HarmonyOS ArkUI Canvas(你相信光吗?)

其他部分

了解了上面的几个Canvas相关的api,剩余的部分稍微动下脑筋,就能够将中心,棒棒和底座一次搞定 啦,代码如下:

          //神光棒中心
          this.context.beginPath()
          this.context.moveTo(width/2-50, height/2)
          this.context.lineTo(width/2+50, height/2)
          this.context.lineTo(width/2+50, height/2+25)
          this.context.lineTo(width/2-50, height/2+25)
          this.context.closePath()
          this.context.stroke()
          this.context.fillStyle = "#eee7b0"
          this.context.fill()
          //神光棒棒棒
          this.context.beginPath()
          this.context.moveTo(width/2-25, height/2+25)
          this.context.lineTo(width/2-25, height/2+25+200)
          this.context.lineTo(width/2+25, height/2+25+200)
          this.context.lineTo(width/2+25, height/2+25)
          this.context.closePath()
          this.context.stroke()
          //神光棒底座
          this.context.beginPath()
          this.context.moveTo(width/2-30, height/2+25+200)
          this.context.lineTo(width/2+30, height/2+25+200)
          this.context.lineTo(width/2+30, height/2+25+200+30)
          this.context.lineTo(width/2-30, height/2+25+200+30)
          this.context.closePath()
          this.context.stroke()
          this.context.fillStyle = "#eee7b0"
          this.context.fill()

HarmonyOS ArkUI Canvas(你相信光吗?)

最终再加上一个倾斜,一切人都能够变成光!

          this.context.rotate(-10 * Math.PI / 180)

HarmonyOS ArkUI Canvas(你相信光吗?)

完好代码:

// @ts-nocheck
@Entry
@Preview
@Component
struct Index {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .onReady(() => {
          let width = this.context.width
          let height = this.context.height
          this.context.lineWidth = 2
          this.context.rotate(-10 * Math.PI / 180)
          //神光棒左边
          this.context.beginPath()
          this.context.moveTo(width/2, height/4)
          this.context.lineTo(width/4, height/8)
          this.context.lineTo(width/4, height/3)
          this.context.arcTo(width/4, height/2, width/2, height/2, 90)
          this.context.closePath()
          this.context.stroke()
          //神光棒右侧
          this.context.beginPath()
          this.context.moveTo(width/2, height/4)
          this.context.lineTo(width/4*3, height/8)
          this.context.lineTo(width/4*3, height/3)
          this.context.arcTo(width/4*3, height/2, width/2, height/2, 90)
          // this.context.closePath()
          this.context.stroke()
          //中心圆形
          this.context.beginPath()
          this.context.arc(width/2, height/3, 40, 0, 360)
          // this.context.stroke()
          var grad = this.context.createRadialGradient(200,200,50, 200,200,200)
          grad.addColorStop(0.0, '#ffd7d556')
          grad.addColorStop(1.0, '#ffcdc555')
          grad.addColorStop(0.5, '#ffffff')
          this.context.fillStyle = grad
          this.context.fill()
          //神光棒中心
          this.context.beginPath()
          this.context.moveTo(width/2-50, height/2)
          this.context.lineTo(width/2+50, height/2)
          this.context.lineTo(width/2+50, height/2+25)
          this.context.lineTo(width/2-50, height/2+25)
          this.context.closePath()
          this.context.stroke()
          this.context.fillStyle = "#eee7b0"
          this.context.fill()
          //神光棒棒棒
          this.context.beginPath()
          this.context.moveTo(width/2-25, height/2+25)
          this.context.lineTo(width/2-25, height/2+25+200)
          this.context.lineTo(width/2+25, height/2+25+200)
          this.context.lineTo(width/2+25, height/2+25)
          this.context.closePath()
          this.context.stroke()
          //神光棒底座
          this.context.beginPath()
          this.context.moveTo(width/2-30, height/2+25+200)
          this.context.lineTo(width/2+30, height/2+25+200)
          this.context.lineTo(width/2+30, height/2+25+200+30)
          this.context.lineTo(width/2-30, height/2+25+200+30)
          this.context.closePath()
          this.context.stroke()
          this.context.fillStyle = "#eee7b0"
          this.context.fill()
        })
    }
    .width('100%')
    .height('100%')
  }
}function centerX<T>(x: any,arg1: number,y: any,arg3: number,z: any,arg5: number,centerX: any,arg7: number,centerY: any,arg9: number) {
throw new Error('Function not implemented.')
}

总结

在编译器的heip->API Reference->画布组件中能够看到Canvans相关的API及介绍,本文参考API文档制作神光棒,迪迦!