前言
昨天华为mate60提早发售,网上撒播,麒麟9000s,“4G改””,“突破列强科技封闭”等字眼撒播在各大社交平台,我对着那些mate60相关文章左看右看,上看下看,竟从鳞次栉比的文字中看出四个字——“遥遥领先”
其实原因是在沸点看见这么一个表情包,然后就用HarmonyOS ArkUI 的 Canvas画了一个神光棒(我没有说华为是国产之光啊,叠甲)。不跑偏了,咱们今天经过画这个神光棒来了解下HarmonyOS ArkUI 的 Canvas
一、Canvas是什么?
Canvas是 ArkUI 供给的画布组件,用于自定义制作图形。它运用类似于HTML5 Canvas的方式进行制作,能够完成高效、灵活的自定义UI界面。Canvas能够完成在画布上自在制作图形,包括线条、矩形、圆形、文本、图片等,并且能够经过操控制作次序和渲染次序来完成图层管理和遮盖作用。
参数:
参数名 | 参数类型 | 必填 | 默许值 | 参数描绘 |
---|---|---|---|---|
context | CanvasRenderingContext2D | 否 | – | 见CanvasRenderingContext2D对象。 |
二、画神光棒
想要画一个神光棒,咱们要先将它拆解,看看它由什么组成,然后咱们就得到了如下公式:
得到公式后咱们一步一步将其画出来,在开端运用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()
解说
-
beginPath():beginPath() 是 canvas 的办法之一,它的作用是创立一个新途径,用于制作图形。新途径创立后,之前制作的途径和样式将被清空。在开端制作新的途径之前,咱们一般需求调用此办法来创立一个新的途径对象。
-
moveTo():的moveTo办法是用于将画笔移动到指定的坐标点。具体语法如下: –
public void moveTo(float x, float y)
其间,x和y别离表明坐标点的横纵坐标。 -
lineTo(): lineTo办法用于在指定坐标处开端制作一条直线。其语法与moveTo相同
-
arcTo(): arcTo() 是 Canvas API 中的途径制作办法之一。它用于制作一段弧线,该弧线的起点和结尾是已知的,可是中心的弧度巨细和轨道需求经过操控点来操控。
arcTo() 办法有四个参数,前两个参数是操控点坐标,中心两个参数是结尾坐标。它的语法如下:
context.arcTo(x1, y1, x2, y2, radius)
在制作途径时,咱们一般先用 moveTo() 办法来设置途径的开始点,然后用 arcTo() 办法来制作一段弧线,最终用 lineTo() 或许其它途径制作办法来弥补途径的其它部分。
运用 arcTo() 办法需求留意以下几点:
- 途径的开始点不能和弧线的起点重合;
- 操控点的坐标和结尾的坐标有必要在同一直线上;
- 操控点和结尾的距离有必要大于弧线的半径,不然将无法制作出弧线;
- 如果要制作出多段弧线,每段弧线的起点和上一段弧线的结尾有必要重合,不然将会构成断点。
-
closePath():用于将当时笔画的起点和结尾衔接起来,构成一个封闭途径。当调用 closePath() 后,下一次的制作操作就会从途径的起点开端,而不是继续上一次途径的结尾。途径的起点默许是最终一个 moveTo() 办法所设置的点。如果当时途径没有进行 moveTo() 操作,则起点自动设置为 (0, 0)。在 closePath() 之后,你能够经过 fill() 或 stroke() 办法来填充或描边途径。如果当时途径没有构成封闭途径(即起点和结尾未衔接),则 closePath() 办法不会产生任何作用。
-
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 时才有用。
作用如下:
同理,咱们只需求改换一下位置坐标,就能将右侧画出来
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()
作用入下
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()
解说:
- 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 能够制作出不同的圆弧形状。
- createRadialGradient 用于创立一个放射性突变的函数,也便是完成在给定的两个圆之间进行颜色突变的功能。具体来说,该办法接纳6个参数:
- centerX: 突变圆的中心点横坐标。
- centerY: 突变圆的中心点纵坐标。
- radius: 突变圆的半径。
- centerX2: 第二个突变圆的中心点横坐标。
- centerY2: 第二个突变圆的中心点纵坐标。
- radius2: 第二个突变圆的半径。
该办法会返回一个突变对象,能够在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()
最终再加上一个倾斜,一切人都能够变成光!
this.context.rotate(-10 * Math.PI / 180)
完好代码:
// @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文档制作神光棒,迪迦!