HarmonyOS ArkUI Canvas(你相信光吗?)

news2024/12/23 18:54:49

文章目录

  • 前言
  • 一、Canvas是什么?
  • 二、画神光棒
    • 1.绘制神光棒左右侧
    • 2.中心圆形
    • 其他部分
  • 总结


前言

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

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

请添加图片描述


一、Canvas是什么?

Canvas是 ArkUI 提供的画布组件,用于自定义绘制图形。它使用类似于HTML5 Canvas的方式进行绘制,可以实现高效、灵活的自定义UI界面。Canvas可以实现在画布上自由绘制图形,包括线条、矩形、圆形、文本、图片等,并且可以通过控制绘制顺序和渲染顺序来实现图层管理和遮盖效果。

参数:

参数名参数类型必填默认值参数描述
contextCanvasRenderingContext2D-见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()

解释

  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 时才有效。

效果如下:

在这里插入图片描述

同理,我们只需要变换一下位置坐标,就能将右侧画出来

          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()

解释:

  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上使用该对象进行绘制。

效果如下:

在这里插入图片描述

其他部分

熟悉了上面的几个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文档绘制神光棒,迪迦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/954704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ABB USC329AE01控制器模块

多通道控制&#xff1a; USC329AE01 控制器模块通常具有多个控制通道&#xff0c;可用于监测和控制不同的过程变量。 通讯接口&#xff1a; 这种模块通常支持各种通讯接口&#xff0c;如以太网、串口&#xff08;RS-232、RS-485&#xff09;、Profibus、Modbus 等&#xff0c;…

提高办公效率,离不开微服务平台框架的助攻!

如今&#xff0c;低代码技术平台获得了很多企业的青睐和喜爱&#xff0c;由于其灵活、易操作、好维护、能提质增效等优势特点&#xff0c;赢得了不少新老客户朋友的追捧。微服务平台框架是其中的一个重要功能&#xff0c;如果想要做好数据资源管理&#xff0c;提高办公协作效率…

提升方法AdaBoost算法

此算法就是一个学习&#xff0c;然后积累&#xff0c;再学习的方法。 大概流程是首先建立一个弱分类&#xff0c;然后计算其错误率&#xff0c;根据错误的样本数给样本分配权重&#xff0c;然后再根据这个样本权重去计算新的最小分类错误率&#xff0c;以此类推&#xff0c;直…

多语言代入电商平台api接口采集唯品会获取vip商品详情数据示例

商品详情API接口的作用和重要性主要体现在以下几个方面&#xff1a; 获取详细商品信息&#xff1a;商品详情API接口提供了获取商品的完整详细信息的功能。这包括商品名称、价格、库存、规格、描述、图片、运费等。这些详细信息对于用户来说是购买决策的重要依据。提供用户购物…

uniapp简单版语音唤醒

第一步&#xff1a; 先登录--- 获取唤醒词 相关网址 百度AI开放平台-全球领先的人工智能服务平台-百度AI开放平台 第二步&#xff1a; 去注册百度云 访问这个网址 百度智能云-登录 去创建应用 请注意自己的 app的打包时候的包名 要填上啊&#xff01;&#xff01;&am…

EOCR-AR电机保护器自动复位的启用条件说明

为适用不同的现场使用需求&#xff0c;施耐德韩国公司推出了带有自动复位功能的模拟型电动机保护器-EOCR-AR。EOCR-AR电机保护器具有过电流、缺相、堵转保护功能&#xff0c;还可根据实际需要设置自动复位时间。 EOCR-AR自动复位的设置方法 如上图&#xff0c;R-TIME旋钮是自动…

如何选择合适的第三方控价服务商

控价是一件对于品牌方、经销商、消费者来说都有益处的事情&#xff0c;但是控价也是一件敏感的事情&#xff0c;要做好控价&#xff0c;不仅要有专业的知识&#xff0c;还要有丰富的经验&#xff0c;因为在平台上控价&#xff0c;除了要尊重平台的规则外&#xff0c;还要熟悉政…

每日一练 | 华为认证真题练习Day106

1、链路聚合技术中&#xff0c;Eth-Trunk可以根据哪些参数来实现流量的负载分担&#xff1f;&#xff08;多选&#xff09; A. 相同的源IP地址或目的IP地址 B. 相同的源端口号或目的端口号 C. 相同的源MAC地址或目的MAC地址 D. 相同的协议类型 2、Truk端口可以允许多个VLAN…

另类创意火爆!小卖靠创意文具走红TikTok

英国一位小卖家结合短视频&#xff0c;靠创意文具一年也赚了十几万美金&#xff0c;而她大多数文具并没有芭比元素。当然&#xff0c;这场“粉色风暴”中&#xff0c;或许她也在酝酿新的创意灵感。 创意文具走红TikTok 在Instagram上&#xff0c;漂亮的“Instagrammable”文具…

Android开发血动脉——Binder机制

Binder是Android中的一个类&#xff0c;它继承了IBinder接口。从IPC角度来说&#xff0c;Binder是Android中的一种跨进程通信方式&#xff0c;Binder还可以理解为一种虚拟的物理设备&#xff0c;它的设备驱动是/dev/binder&#xff0c;该通信方式在linux中没有。从Android Fram…

cocosCreator 之 3.8打包注意事项

版本&#xff1a; v3.8.0 环境&#xff1a; Mac 介绍 曾编写过一篇文章&#xff1a; cocosCreator笔记 之 Android打包 使用的版本是&#xff1a; v3.4.0 在官方发布最新版本3.8.0后&#xff0c;就编写了Demo尝试打包发布下&#xff0c;结果一路的报错问题。 写此博客&…

linux 下安装chrome 和 go

1. 安装google-chrome 1.1 首先下载google-chrome.deb安装包 之后 安装 gdebi包 sudo apt install gdebi 1.2 安装所要安装的软件 sudo gdebi code_1.81.1-1691620686_amd64.deb 1.3 解决Chrome无法启动问题 rootubuntu:~/Downloads# whereis google-chrome google-chrome…

去除字符串中的数字(字符串的拼接memcpy(str2[j],str1[i],1);)

1 题目 去除字符串中的数字 删除一个字符串中的所有数字字符。 例如&#xff1a; 输入&#xff1a;cat4lion25film 输出&#xff1a;catlionfilm 2 考察点 1 字符串的拼接使用2 数字和字母的acill码 3 答案 3.1 官网答案&#xff08;厉害了方法学习下&#xff09; /* 删…

mysql数据无法写入汉字的解决办法

存在问题&#xff1a; mysql数据库不能写入汉字&#xff1b; 解决方案&#xff1a; 打开表设计&#xff0c;把相应位置字符集改为utf-8

【爬虫】实验项目一:文本反爬网站的分析和爬取

目录 一、实验目的 二、实验预习提示 ​编辑 三、实验内容 四、实验要求 五、实验过程 1. 基本要求&#xff1a; 2. 改进要求A 3. 改进要求B: 六、资料 1.实验框架代码&#xff1a; 2.OpenSSL&#xff1a;Win32/Win64 OpenSSL Installer for Windows - Shining Light…

数据时代的必备利器:数据可视化工具的崭新价值

在当今信息时代&#xff0c;数据扮演着越来越重要的角色&#xff0c;而数据的可视化呈现正是一种强大的工具&#xff0c;能够帮助我们更好地理解和利用这些数据。虽然Excel和PPT在处理数据方面有着不可否认的作用&#xff0c;但在处理大规模、复杂数据时&#xff0c;数据可视化…

18.Oauth2-微服务认证

1.Oauth2 OAuth 2.0授权框架支持第三方支持访问有限的HTTP服务&#xff0c;通过在资源所有者和HTTP服务之间进行一个批准交互来代表资源者去访问这些资源&#xff0c;或者通过允许第三方应用程序以自己的名义获取访问权限。 为了方便理解&#xff0c;可以想象OAuth2.0就是在用…

百度等8家企业首批上线大模型服务;大语言模型微调之道

&#x1f989; AI新闻 &#x1f680; 百度等8家企业首批上线大模型服务 摘要&#xff1a;百度、字节、中科院旗下8家企业/机构的大模型通过备案&#xff0c;正式面向公众提供服务。百度旗下AI大模型产品文心一言率先开放&#xff0c;用户可下载App或登录官网体验。百川智能也…

【前端自动化部署】,Devops,CI/CD

DevOps 提到Jenkins&#xff0c;想到的第一个概念就是 CI/CD 在这之前应该再了解一个概念。 DevOps Development 和 Operations 的组合&#xff0c;是一种方法论&#xff0c;并不特指某种技术或者工具。DevOps 是一种重视 Dev 开发人员和 Ops 运维人员之间沟通、协作的流程。…

高级DBA手把手教你Mysql大数据量批量导入人大金仓国产数据库方法(全网最详细)

Mysql数据批量导入人大金国产数据库方法 参考下面地址&#xff0c;先安装好整体的安装包到电脑上 https://blog.csdn.net/nasen512/article/details/132599267迁移工具安装方法查看我另一篇上面地址的文章&#xff0c;作者是全量安装金仓自带的windows迁移程序! 1、打开官方…