当前位置: 首页 > news >正文

ArkUI框架之Canvas 画布

Canvas 画布

Canvas提供画布组件,用于自定义绘制图形,开发者使用CanvasRenderingContext2D对象在Canvas组件上进行绘制,绘制对象可以是基础形状、文本、图片等。

1.Canvas 快速入门

onReady(event: () => void)是Canvas组件初始化完成时的事件回调,调用该事件后,可获取Canvas组件的确定宽高,进一步使用CanvasRenderingContext2D对象调用相关API进行图形绘制。

@Entry@Componentstruct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column(){Canvas(this.context).width('100%').height('100%').backgroundColor(Color.Pink).onReady(() => {this.context.fillStyle = Color.Yellow; 		//设置填充色this.context.fillRect(50, 50, 100, 100); 	//填充矩形})}.height('100%').width('100%')}}

2.常用绘制方法

CanvasRenderingContext2D对象提供了大量的属性和方法,可以用来绘制文本、图形,处理像素等,是Canvas组件的核心。常用接口有fill(对封闭路径进行填充)、clip(设置当前路径为剪切路径)、stroke(进行边框绘制操作)等等,同时提供了fillStyle(指定绘制的填充色)、globalAlpha(设置透明度)与strokeStyle(设置描边的颜色)等属性修改绘制内容的样式。

2.1 绘制矩形

以下是绘制矩形的方法

rect(x: number,		//矩形左上角x坐标y: number, 		//矩形左上角y坐标w: number, 		//矩形宽度h: number			//矩形高度
): void

在Canvas画布上绘制一个矩形
在这里插入图片描述

@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column(){Canvas(this.context).width(300).height(300).backgroundColor(Color.Pink).onReady(() => {//1. 绘制一个矩形,带边框和填充色this.context.beginPath()//1.1 矩形范围(x坐标,y坐标,宽,高)this.context.rect(20,20,200,100)//1.2 矩形边框this.context.strokeStyle = Color.Black    //边框颜色this.context.lineWidth = 2    //边框粗细this.context.stroke()         //绘制边框//1.3 矩形填充色this.context.fillStyle = Color.Yellowthis.context.fill()})}.height("100%").width('100%')}
}

2.2 绘制圆形

以下是绘制圆形的方法

arc(x: number, 				//圆心x坐标y: number, 				//圆心y坐标radius: number, 	//圆的半径startAngle: number, 	//开始弧度endAngle: number, 		//结束弧度counterclockwise?: boolean	//是否逆时针默认false
): void

在Canvas画布上绘制一个圆形
在这里插入图片描述

@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column(){Canvas(this.context).width(300).height(300).backgroundColor(Color.Pink).onReady(() => {//1. 绘制一个圆形,带边框和填充色this.context.beginPath()//1.1 圆形范围(圆心x坐标,圆心y坐标,半径,开始弧度,结束弧度)this.context.arc(150,150,100,0,Math.PI*2) //1.2 圆形边框this.context.strokeStyle = Color.Black    //边框颜色this.context.lineWidth = 2    //边框粗细this.context.stroke()         //绘制边框//1.3 圆形填充色this.context.fillStyle = Color.Yellowthis.context.fill()})}.height("100%").width('100%')}
}

2.3 绘制椭圆

绘制椭圆的方法

ellipse(x: number, 	//圆心x轴坐标y: number, 	//圆心y坐标radiusX: number, 	//x轴半径radiusY: number, 	//y轴半径rotation: number, //椭圆整体旋转的弧度startAngle: number,	//起点弧度endAngle: number		//终点弧度
): void

在这里插入图片描述

@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column() {Canvas(this.context).width(300).height(300).backgroundColor(Color.Pink).onReady(() => {//1. 绘制一个矩形,带边框和填充色this.context.beginPath()//1.1 椭圆范围(圆心x坐标,圆心y坐标,x轴半径,y轴半径, 旋转弧度, 起始弧度,结束弧度宽)this.context.ellipse(150, 150, 120, 80, 0, 0, Math.PI * 2)//1.2 矩形边框this.context.strokeStyle = Color.Black //边框颜色this.context.lineWidth = 2 //边框粗细this.context.stroke() //绘制边框//1.3 矩形填充色this.context.fillStyle = Color.Yellowthis.context.fill()})}.height("100%").width('100%')}
}

2.4 绘制直线

绘制如下图所示的三条直线,确定一条直线至少需要2个端点。
在这里插入图片描述

@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column() {Canvas(this.context).width(300).height(300).backgroundColor(Color.Pink).onReady(() => {//1. 创建一条新路径this.context.beginPath()//1.1 设置线条颜色this.context.strokeStyle = Color.Black//1.1 设置线条端点样式(butt两端方形)this.context.lineCap = "butt"//1.2 设置线条宽度(线粗)this.context.lineWidth = 8//1.3 移动到(20,20)坐标点this.context.moveTo(20,20)//1.4 连接到 (120,20) 坐标点this.context.lineTo(120,20) //1.5 绘制线条this.context.stroke()//2. 创建一条新路径this.context.beginPath()//2.1 设置线条端点样式(square两端方形,两端新增长度为宽度线宽度的一半)this.context.lineCap = "square"this.context.lineWidth = 8this.context.moveTo(20,40)this.context.lineTo(120,40)this.context.stroke()//3. 创建一条新路径this.context.beginPath()//3.1 设置线条端点样式(round线条端点为圆形)this.context.lineCap = 'round'this.context.lineWidth = 8this.context.moveTo(20, 60)this.context.lineTo(120, 60)this.context.stroke() })}.height("100%").width('100%')}
}

2.5 交点样式

绘制线条时,相交点可以是圆角也可以是尖角。通过this.context.lineJoin 属性设置 设置
● this.context.lineJoin = ‘miter’ 设置交点为尖叫
● this.context.lineJoin = ‘round’ 设置交点为圆角

在这里插入图片描述

@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column() {Canvas(this.context).width(300).height(300).backgroundColor(Color.Pink).onReady(() => {//1. 绘制多边形this.context.beginPath()this.context.lineWidth = 8this.context.lineJoin = 'miter' //尖角this.context.moveTo(20, 20)this.context.lineTo(120, 20)this.context.lineTo(120, 120)this.context.lineTo(20, 120)this.context.closePath()this.context.stroke()//2. 绘制多边形this.context.beginPath()this.context.lineWidth = 8this.context.lineJoin = "round"	//圆角this.context.strokeStyle = Color.Redthis.context.moveTo(70, 20)this.context.lineTo(20, 70)this.context.lineTo(70, 120)this.context.lineTo(120, 70)this.context.closePath()this.context.stroke()})}.height("100%").width('100%')}
}

2.6 绘制文本

在画布上绘制两行文本,一种是填充色文本,一种是描边文本。
在这里插入图片描述

@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column() {Canvas(this.context).width(300).height(300).backgroundColor(Color.Pink).onReady(() => {//绘制填充类文本this.context.beginPath()this.context.font = '40vp serif'; //大小、字体this.context.fillStyle = Color.Yellowthis.context.fillText("Hello World!", 0, 50);this.context.closePath()//绘制描边类文本this.context.beginPath()this.context.font = '30vp serif'  //大小、字体this.context.strokeStyle = Color.Redthis.context.lineWidth = 1this.context.strokeText("Hello HarmonyOS NEXT",0,100,300)})}.height("100%").width('100%')}
}

2.7 绘制渐变色

在矩形范围内从左到右按照太阳光色谱从红色渐变到紫色
在这里插入图片描述

  • 线性渐变
@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column() {Canvas(this.context).width("100%").height("100%").backgroundColor(Color.Pink).onReady(() => {const width = this.context.width//1. 线性渐变//创建一个线性渐变色的CanvasGradient对象let grad = this.context.createLinearGradient(0, 0, width, 0)//为CanvasGradient对象设置渐变断点值,包括偏移和颜色const colors: string[] = ["#FF0000", //# 红色"#FF4500", //# 橙红色"#FFA500", //# 橙色"#FFFF00", //# 黄色"#90EE90", //# 浅黄绿色(偏向绿色过渡)"#00FFFF", //# 青绿色(但在此作为绿色到蓝色的过渡色)"#87CEEB", //# 天蓝色"#800080", //# 紫色"#8B008B", //# 深紫色"#4B0082",//# 靛蓝色(偏向紫色)]grad.addColorStop(0.0, colors[0]);grad.addColorStop(0.1, colors[1]);grad.addColorStop(0.2, colors[2]);grad.addColorStop(0.3, colors[3]);grad.addColorStop(0.4, colors[4]);grad.addColorStop(0.5, colors[5]);grad.addColorStop(0.6, colors[6]);grad.addColorStop(0.8, colors[7]);grad.addColorStop(0.9, colors[8]);grad.addColorStop(1.0, colors[9]);//用CanvasGradient对象填充矩形this.context.fillStyle = grad;this.context.fillRect(0, 0, width, 100);})}.height("100%").width('100%')}
}
  • 径向渐变
    在这里插入图片描述
createRadialGradient(x0: number, 	//起点圆心x坐标y0: number,		//起点圆心y坐标r0: number, 	//起点圆半径x1: number, 	//终点圆心x坐标y1: number, 	//终点圆心y坐标r1: number		//终点圆半径
): CanvasGradient
@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {Column() {Canvas(this.context).width("100%").height("100%").backgroundColor(Color.Pink).onReady(() => {const width = this.context.width//1. 径向渐变//创建一个渐变色的CanvasGradient对象let grad = this.context.createRadialGradient(150, 150, 30, 150, 150, 150)//为CanvasGradient对象设置渐变断点值,包括偏移和颜色grad.addColorStop(0.0, '#FF0000');grad.addColorStop(0.5, '#FFFFFF');grad.addColorStop(1.0, '#BDDB69');//用CanvasGradient对象填充矩形this.context.fillStyle = grad;this.context.fillRect(0, 0, 300, 300);})}.height("100%").width('100%')}
}

2.8 绘制图像

如图所示将图像绘制在Canvas画布上;截取屏幕上

@Entry
@Component
struct CanvasDemo {//画笔配置对象,true表示开启抗锯齿private settings: RenderingContextSettings = new RenderingContextSettings(true)//画笔对象,传递画笔配置对象private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600)private img: ImageBitmap = new ImageBitmap("/images/1234.jpg")build() {Column() {Canvas(this.context).width("100%").height("100%").backgroundColor(Color.Pink).onReady(() => {let offContext = this.offCanvas.getContext("2d", this.settings)// 使用drawImage接口将图片画在(0,0)为起点,宽高130的区域offContext.drawImage(this.img, 0, 0, 150, 150);// 使用getImageData接口,获得canvas组件区域中,(50,50)为起点,宽高130范围内的绘制内容let imagedata = offContext.getImageData(50, 50, 130, 130);// 使用putImageData接口将得到的ImageData画在起点为(150, 150)的区域中offContext.putImageData(imagedata, 150, 150); // 将离屏绘制的内容画到canvas组件上let image = this.offCanvas.transferToImageBitmap();this.context.transferFromImageBitmap(image); })}.height("100%").width('100%') }
}
http://www.xdnf.cn/news/1382887.html

相关文章:

  • 什么是最小二乘法
  • 二、开关电源的EMC改善措施
  • CVPR2025丨VL2Lite:如何将巨型VLM的“知识”精炼后灌入轻量网络?这项蒸馏技术实现了任务专用的极致压缩
  • 虚幻基础:角色变换角色视角蒙太奇运动
  • 基于SpringBoot的老年人健康数据远程监控管理系统【2026最新】
  • 嵌入式开发学习———Qt软件环境下的C++学习(七)
  • 图论基础篇
  • Mybatis中缓存机制的理解以及优缺点
  • 微服务相关面试题
  • stable-baseline3介绍
  • 个人博客运行3个月记录
  • mac m4执行nvm install 14.19.1报错,安装低版本node报错解决
  • 【STM32】G030单片机的窗口看门狗
  • Flutter:ios打包ipa,证书申请,Xcode打包,完整流程
  • LeetCode Hot 100 第7天
  • mac系统本地部署Dify步骤梳理
  • 仓颉编程语言青少年基础教程:输入输出
  • 模拟实现Linux中的进度条
  • [Mysql数据库] 知识点总结5
  • 天津医科大学肿瘤医院冷热源群控系统调试完成:以 “精准控温 + 高效节能” 守护医疗核心场景
  • 实战演练(一):从零构建一个功能完备的Todo List应用
  • Spring事务管理机制深度解析:从JDBC基础到Spring高级实现
  • 力扣(LeetCode) ——965. 单值二叉树(C语言)
  • C#写的一键自动测灯带的应用 AI帮写的。
  • [灵动微电子 MM32BIN560CN MM32SPIN0280]读懂电机MCU之串口DMA
  • list 手动实现 1
  • 学习日志40 python
  • 微服务即时通信系统(十三)--- 项目部署
  • 【后端】微服务后端鉴权方案
  • 虚函数指针和虚函数表的创建时机和存放位置