HarmonyOS Development: Simply Customize a Drawing Board



This content originally appeared on DEV Community and was authored by 程序员一鸣

Foreword 

this article is based on Api12 

this article mainly uses Canvas to draw a simple drawing board, which can change the color, brush thickness and delete operation. It mainly applies the drawing path function in CanvasRenderingContext2D. We can see the basic effect. 

Image description

If you draw at will on a drawing board, the existence of Canvas is indispensable. Hongmeng provides us with the Canvas component. Using it, we can draw all kinds of desired graphics on it. There are two construction parameters and only one can be received. context parameter, mainly used to set the ability to draw, in addition context parameter, you can also receive an ImageAIOptions parameter, which is mainly used to require when AI analyzes options, it is generally enough to pass a parameter.

 

(context?: CanvasRenderingContext2D | DrawingRenderingContext): CanvasAttribute

CanvasRenderingContext2D has more function settings than DrawingRenderingContext and is compatible with its own functions. Therefore, we recommend that you use CanvasRenderingContext2D for drawing elements. 

Set Canvas 

Canvas is a component that we can use like any other component.

 

Canvas(this.context)
        .width('100%')
        .height('100%')

A CanvasRenderingContext2D object is passed.

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

The RenderingContextSettings parameter is used to configure the parameters of the CanvasRenderingContext2D object. You can set whether anti-aliasing is enabled. 

Path drawing 

path drawing, including the starting path of the finger press, the moving path to the specified point, and the path connection to the specified point and the end of the final path can make the lines more silky and more in line with normal use.

 

.onTouch((event: TouchEvent) => {
          switch (event.type) {
            case TouchType.Down://
              let downTouch = event.touches[0]
              this.context.beginPath()
              this.context.moveTo(downTouch.x, downTouch.y)
              break
            case TouchType.Move:
              let touch = event.touches[0]
              this.context.lineTo(touch.x, touch.y)
              this.context.stroke()
              break
            case TouchType.Up:
              this.context.closePath()
              break
          }
        })

Set Anti-aliasing 

by setting anti-aliasing, you can remove the burrs of the lines and make the lines silky and smooth.

 

Canvas(this.context)
        .width('100%')
        .height('100%')
        .onReady(() => {
          this.settings.antialias = true
          this.context.lineCap = "round"
        })

Clear operation


 

 this.context.clearRect(0, 0, this.context.width, this.context.height)

full Code


 

@Entry
@Component
struct Index {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  private mColors: string[] =
    ["#000000", "#ffffff", "#FF050C", "#FF7F1D", "#FFE613", "#B2FF29", "#31FFCA", "#2253FF", "#DA25FF", "#FFA687",
      "#ACFFD3", "#98C8FF",
      "#B8ACFF", "#FFCFC5", "#FFDF91"]
  @State showListColor: boolean = true
  @State sliderProgress: string = ""

  build() {
    Column() {

      Canvas(this.context)
        .width('100%')
        .height('100%')
        .onReady(() => {
          this.settings.antialias = true
          this.context.lineCap = "round"
        })
        .onTouch((event: TouchEvent) => {
          switch (event.type) {
            case TouchType.Down:
              let downTouch = event.touches[0]
              this.context.beginPath()
              this.context.moveTo(downTouch.x, downTouch.y)
              break
            case TouchType.Move:
              let touch = event.touches[0]
              this.context.lineTo(touch.x, touch.y)
              this.context.stroke()
              break
            case TouchType.Up:
              this.context.closePath()
              break
          }
        })
        .layoutWeight(1)


      List({ space: 10 }) {
        ForEach(this.mColors, (item: string, _: number) => {
          ListItem() {
            Text()
              .width(20)
              .height(20)
              .backgroundColor(item)
              .borderRadius(20)
              .border({ width: 1, color: "#e8e8e8" })
              .onClick(() => {
                this.context.strokeStyle = item
              })

          }
        })
      }
      .width("100%")
      .height(40)
      .listDirection(Axis.Horizontal)
      .scrollBar(BarState.Off)
      .alignListItem(ListItemAlign.Center)
      .border({ width: { top: 1 }, color: "#e8e8e8" })
      .visibility(this.showListColor ? Visibility.Visible : Visibility.Hidden)

      Slider({
        value: 0,
        min: 0,
        max: 50,
        style: SliderStyle.OutSet
      })
        .showTips(true, this.sliderProgress)
        .trackThickness(5)
        .onChange((value: number, _: SliderChangeMode) => {
          this.sliderProgress = value.toString()
          this.context.lineWidth = value
        })

      Row() {

        Image($r("app.media.canvas_del"))
          .width(30)
          .height(30)
          .borderRadius(30)
          .border({ width: 1, color: "#e8e8e8" })
          .padding(5)
          .onClick(() => {

            this.context.strokeStyle = "#ffffff"
          })

        Image($r("app.media.canvas_clear"))
          .width(30)
          .height(30)
          .borderRadius(30)
          .border({ width: 1, color: "#e8e8e8" })
          .margin({ left: 20 })
          .padding(5)
          .onClick(() => {

            this.context.clearRect(0, 0, this.context.width, this.context.height)
          })
      }.width("100%")
      .height(50)
      .border({ width: { top: 1 }, color: "#e8e8e8" })
      .justifyContent(FlexAlign.Center)
    }
  }
}

related Summary 

sketchpad, the most important thing is to draw, to ensure the continuity of line drawing, this is very important, and the beginPath method must be called, otherwise change the color and draw will appear discontinuous and color setting error.


This content originally appeared on DEV Community and was authored by 程序员一鸣