鸿蒙开发-画布综合示例

devtools/2025/3/1 13:13:24/

以下是一个更复杂的ArkTS示例,它展示了如何在画布上绘制多个形状(包括圆形、矩形和文本),并处理触摸事件来改变画布上的某些属性(如颜色)。

示例代码

import { Color, Point } from '@ohos.build.attr';
import canvas from '@ohos.canvas';// 自定义画布组件
@Component
struct InteractiveCanvasComponent {@Prop(Color) backgroundColor: Color = Color.White; // 画布背景颜色@Prop(Color) circleColor: Color = Color.Blue; // 圆形颜色@Prop(Color) rectColor: Color = Color.Green; // 矩形颜色@Prop(number) circleRadius: number = 50; // 圆形半径@Prop(number) rectWidth: number = 100; // 矩形宽度@Prop(number) rectHeight: number = 50; // 矩形高度@Prop(string) text: string = "Hello, ArkTS!"; // 文本内容@Prop(Color) textColor: Color = Color.Black; // 文本颜色@Prop(number) fontSize: number = 24; // 字体大小// 触摸事件处理@State private lastTouchPoint: Point | null = null;private handleTouch(event: TouchEvent) {if (event.type === 'touchstart') {this.lastTouchPoint = { x: event.touches[0].x, y: event.touches[0].y };// 这里可以添加逻辑来改变画布上的颜色或形状// 例如,随机改变圆形颜色this.circleColor = this.getRandomColor();}}// 随机生成颜色private getRandomColor(): Color {const letters = '0123456789ABCDEF';let color = '#';for (let i = 0; i < 6; i++) {color += letters[Math.floor(Math.random() * 16)];}// 由于ArkTS中的Color类型可能是特定的枚举或对象,这里需要转换或映射到实际的颜色值// 假设有一个函数可以将十六进制字符串转换为ArkTS的Color对象// 例如:Color.fromHex(color) (注意:这个函数是假设的,具体实现取决于ArkTS的API)// 但由于API可能不同,这里直接返回字符串作为示例// 在实际项目中,你需要根据ArkTS的Color类型进行转换return color as any as Color; // 这里使用类型断言来模拟转换,实际项目中应使用正确的转换方法}// 绘制逻辑private draw(canvasContext: canvas.CanvasRenderingContext2D, width: number, height: number) {// 绘制背景canvasContext.fillStyle = this.backgroundColor;canvasContext.fillRect(0, 0, width, height);// 绘制圆形canvasContext.beginPath();const centerX = width / 2;const centerY = height / 2;canvasContext.arc(centerX, centerY, this.circleRadius, 0, 2 * Math.PI);canvasContext.fillStyle = this.circleColor;canvasContext.fill();canvasContext.closePath();// 绘制矩形const rectX = centerX - this.rectWidth / 2;const rectY = centerY + this.circleRadius + 10; // 将矩形放置在圆形下方canvasContext.beginPath();canvasContext.rect(rectX, rectY, this.rectWidth, this.rectHeight);canvasContext.fillStyle = this.rectColor;canvasContext.fill();canvasContext.closePath();// 绘制文本const textX = centerX - (this.text.length * this.fontSize / 2); // 简单文本居中(未考虑字体宽度差异)const textY = rectY + this.rectHeight + 20; // 将文本放置在矩形下方canvasContext.font = `${this.fontSize}px sans-serif`;canvasContext.fillStyle = this.textColor;canvasContext.fillText(this.text, textX, textY);}build() {Canvas().width('100%').height('100%').onDraw((canvasContext: canvas.CanvasRenderingContext2D, width: number, height: number) => {this.draw(canvasContext, width, height);}).onTouch((event: TouchEvent) => {this.handleTouch(event);});}
}// 页面组件
@Entry
@Component
struct MyPage {build() {Column() {// 使用自定义画布组件InteractiveCanvasComponent().width('300vp').height('300vp');// 可以添加其他UI元素,如按钮、输入框等,用于进一步控制画布}.justifyContent(FlexAlign.Center).alignItems(FlexAlign.Center);}
}

说明

  1. 自定义画布组件InteractiveCanvasComponent是一个包含多个属性和绘制逻辑的自定义组件。它使用@Prop装饰器来接收外部传递的属性值,并使用@State装饰器来管理内部状态(如触摸点)。
  2. 触摸事件处理handleTouch方法用于处理触摸事件。在这个示例中,它仅在touchstart事件发生时被调用,并随机改变圆形的颜色。你可以根据需要添加更多的触摸事件处理逻辑(如touchmovetouchend)。
  3. 绘制逻辑draw方法包含绘制背景、圆形、矩形和文本的逻辑。它使用canvasContext对象来执行绘制操作。
  4. 页面组件MyPage是页面组件,它使用InteractiveCanvasComponent并设置其宽度和高度。你还可以在页面上添加其他UI元素来进一步控制画布。

注意事项

  • 由于ArkTS的API可能会随着版本的更新而变化,因此在实际项目中,你需要根据最新的API文档来调整代码。
  • 在这个示例中,getRandomColor方法返回了一个十六进制字符串作为颜色值。在实际项目中,你需要根据ArkTS的Color类型来转换或映射这个值。如果ArkTS提供了从十六进制字符串到Color对象的转换函数,你应该使用那个函数。
  • 触摸事件处理中的this.lastTouchPoint在这个示例中没有被进一步使用,但你可以根据需要在绘制逻辑或其他地方使用它。
  • 文本绘制时使用了简单的居中逻辑,但没有考虑字体宽度的差异。在实际项目中,你可能需要使用更精确的文本布局算法。
    在这里插入图片描述

http://www.ppmy.cn/devtools/163624.html

相关文章

【蓝桥杯集训·每日一题2025】 AcWing 5439. 农夫约翰真的种地 python

AcWing 5439. 农夫约翰真的种地 题目描述 Week 2 2月27日 农夫约翰在他的农场种植了 N N N 个芦笋&#xff0c;编号 1 ∼ N 1 \sim N 1∼N。 其中&#xff0c;第 i i i 个芦笋的初始高度为 h i h_i hi​&#xff0c;每经过一天高度会增长 a i a_i ai​。 给定一个 0…

Python在实际工作中的运用-指定目录内所有Excel文件转CSV

闲来无事浏览到《【办公自动化】使用Python批量处理Excel文件并转为csv文件》这篇博文&#xff0c;关于多层目录Excel转Csv在处理过程中略显繁复&#xff0c;而且灵活度不高&#xff0c;代码如下&#xff1a; import pandas as pd import os from datetime import datetime # …

dify镜像拉取不下来如何解决

# 启动docker(一定要先启动再添加dns) systemctl start docker #添加国境镜像和dns sudo vim /etc/docker/daemon.json { "registry-mirrors":[ "https://dockerpull.pw"&#xff0c; "https://dockerhub.icu", "https://hu…

Redis 分布式锁

概念 在⼀个分布式的系统中&#xff0c;也会涉及到多个节点访问同⼀个公共资源的情况&#xff0c;此时就需要通过锁来做互斥控制&#xff0c;避免出现类似于 "线程安全" 的问题。但 C 的 std::mutex 只能在当前进程中⽣效, 在分布式的这种多个进程多个主机的场景下就…

C++核心指导原则: 源文件

C Core Guidelines 整理目录 哲学部分接口(Interface)部分函数部分类和类层次结构部分枚举部分资源管理部分表达式和语句部分性能部分并发和并行错误处理常量和不可变性泛型编程源文件 源文件规则 SF.1: Use a .cpp suffix for code files and .h for interface files if you…

微信小程序自定义导航栏,胶囊菜单按钮高度适配问题

抽离公共方法用条件编译对微信小程序&#xff0c;抖音小程序适配 公共组件模块建立一个导航模块 <template><view class"layout"><view class"navbar" ><view class"statusBar" :style"{height:getStatusBarHeight()p…

微信小程序记录用户在图书详情页面停留时间--即阅读时间,如果超过两小时,则每小时提醒用户一次

在微信小程序中记录用户在图书详情页面的停留时间&#xff0c;并根据条件&#xff08;如超过两小时&#xff09;进行提醒&#xff0c;可以通过以下步骤实现。以下是详细的实现方案&#xff1a; 1. 实现思路 记录进入页面的时间&#xff1a;当用户进入图书详情页面时&#xff0…

SpringSecurity踢出指定用户

SpringSecurity中可以使用 SessionRegistry 的实现类 SessionRegistryImpl 来获取session相关信息&#xff0c;可以通过这个实现类来踢出用户。 SpringSecurity配置 EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {AutowiredISysUser…