鸿蒙开发-画布综合示例

以下是一个更复杂的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在这个示例中没有被进一步使用,但你可以根据需要在绘制逻辑或其他地方使用它。
  • 文本绘制时使用了简单的居中逻辑,但没有考虑字体宽度的差异。在实际项目中,你可能需要使用更精确的文本布局算法。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值