欢迎光临
我们一直在努力

HarmonyOS应用开发实战:小事记 - Canvas 画布基础:CanvasRenderingContext2D 的路径绘制与坐标系统

页面预览

前言

Canvas 画布是 ArkUI 中自定义绘制的核心组件,使用 CanvasRenderingContext2D 对象进行路径绘制、图形渲染和文本输出。理解 Canvas 的坐标系统和路径绘制 API,是实现自定义图表、动画和特效的基础。本文以小事记(xiaoshiji_ohos_app) 的自定义图表场景为背景,深入解析 Canvas 画布的基础用法。

本文参考 HarmonyOS 官方文档:arkts-drawing-customization-on-canvas.md 和 CanvasRenderingContext2D 参考。

一、Canvas 的基本用法

1.1 基本结构

// Canvas 画布的基本用法
@Entry
@Component
struct CanvasExample {
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);

build() {
Column() {
Canvas(this.context)
.width('100%')
.height(300)
.backgroundColor('#F8F9FA')
.onReady(() => {
this.draw();
})
}
.width('100%')
.height('100%')
}

draw(): void {
// 绘制矩形
this.context.strokeRect(50, 50, 200, 150);

// 绘制圆形
this.context.beginPath();
this.context.arc(150, 125, 50, 0, Math.PI * 2);
this.context.stroke();
}
}

二、坐标系统

2.1 坐标原点

Canvas 的坐标原点在左上角 (0, 0),X 轴向右为正,Y 轴向下为正:

(0, 0) ──────────→ X



Y

三、路径绘制 API

3.1 常用 API

API说明参数
beginPath 开始路径
moveTo(x, y) 移动到 坐标
lineTo(x, y) 画线到 坐标
arc(x, y, r, s, e) 画弧 圆心、半径、起止角度
rect(x, y, w, h) 矩形 位置、大小
stroke() 描边
fill() 填充

四、常见问题

4.1 Canvas 不显示

问题:Canvas 组件没有显示绘制内容。

解决方案:确保在 onReady 回调中执行绘制。

五、

// Canvas 动画循环
function animate(): void {
this.context.clearRect(0, 0, 300, 300);
this.draw();
requestAnimationFrame(() => { this.animate(); });
}

最佳实践

策略说明效果
onReady 绘制 在组件就绪后绘制 确保 Canvas 可用
清除画布 使用 clearRect 清除 重绘
保存状态 使用 save/restore 不影响其他绘制

八、拓展阅读

本节汇总了与本文主题相关的扩展阅读材料,帮助读者深入理解相关技术细节。

8.1 官方文档

  • 开发者指南:HarmonyOS 应用开发概述
  • API 参考:ArkTS API 参考

8.2 相关技术文章

  • 性能优化最佳实践
  • 常见问题排查指南

8.3 社区资源

  • 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

十、最佳实践与优化建议

在实际开发中,合理运用上述技术可以显著提升应用的性能和用户体验。以下是几个关键的最佳实践建议:

10.1 性能优化要点

优化方向具体措施预期效果
渲染性能 减少不必要的组件重建 提升帧率
内存管理 及时释放不再使用的资源 降低内存占用
响应速度 避免在主线程执行耗时操作 提升交互流畅度

10.2 推荐实践步骤

按照以下步骤进行优化:

  • 使用 DevEco Studio 的 Profiler 工具分析当前性能瓶颈
  • 针对识别出的热点进行针对性优化
  • 通过单元测试和集成测试验证优化效果
  • 在真机环境下进行回归测试
  • 10.3 代码示例

    // 推荐的最佳实践示例
    @Component
    export struct OptimizedComponent {
    // 使用 @State 管理最小粒度的状态
    @State private isActive: boolean = false;

    build() {
    Column() {
    Text(this.isActive ? '激活' : '未激活')
    .fontSize(16)
    }
    .onClick(() => {
    // 使用 animateTo 实现平滑过渡
    animateTo({ duration: 300 }, () => {
    this.isActive = !this.isActive;
    });
    });
    }
    }

    最佳实践提示:在编写代码时,始终遵循 ArkUI 的性能优化原则,避免在 build() 方法中执行复杂计算或频繁的状态更新。

    十、进一步学习与拓展

    掌握以上内容后,可以进一步探索以下相关主题,深化对 HarmonyOS 开发的理解:

    10.1 推荐学习路径

    学习阶段主题预期目标
    基础阶段 掌握核心概念和 API 用法 能够独立完成基本功能开发
    进阶阶段 理解底层原理和最佳实践 能够优化应用性能和用户体验
    高级阶段 掌握架构设计和性能调优 能够主导复杂项目的技术方案

    10.2 实践项目建议

    建议通过以下实践项目巩固所学知识:

  • 基于小事记项目,尝试独立实现一个类似的功能模块
  • 阅读 HarmonyOS 官方 Sample 代码,学习最佳实践
  • 参与开源社区,贡献代码或文档
  • 10.3 相关资源

    • HarmonyOS 官方文档:提供完整的 API 参考和开发指南
    • DevEco Studio 文档:包含 IDE 使用技巧和调试方法
    • 开源社区:获取项目源码和开发经验

    学习建议:理论与实践相结合,在阅读文档的同时动手编写代码,才能更好地掌握 HarmonyOS 应用开发技能。

    10.4 拓展阅读

    以下资源可以加深对本文内容的理解:

  • HarmonyOS 官方开发者文档提供了最权威的 API 参考和最佳实践指南
  • 开源社区的项目源码是学习实际应用开发的宝贵资源
  • DevEco Studio 的代码示例模板可以帮助快速上手
  • 资源类型推荐指数适用人群
    官方文档 ⭐⭐⭐⭐⭐ 所有开发者
    开源项目 ⭐⭐⭐⭐ 中级开发者
    技术博客 ⭐⭐⭐ 入门开发者

    学习路径:建议按照“官方文档 → 开源项目 → 实践项目“的路径循序渐进地学习。

    十、完整示例:Canvas 绘图封装

    将 Canvas 绘图操作封装为可复用的绘制工具,可以简化图形绘制逻辑。

    10.1 绘图工具封装

    // CanvasUtil.ets — Canvas 绘图工具
    import { CanvasRenderingContext2D } from '@kit.ArkUI';

    export class CanvasUtil {
    static drawRoundRect(
    ctx: CanvasRenderingContext2D,
    x: number, y: number, w: number, h: number, r: number
    ): void {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w – r, y);
    ctx.arcTo(x + w, y, x + w, y + r, r);
    ctx.lineTo(x + w, y + h – r);
    ctx.arcTo(x + w, y + h, x + w – r, y + h, r);
    ctx.lineTo(x + r, y + h);
    ctx.arcTo(x, y + h, x, y + h – r, r);
    ctx.lineTo(x, y + r);
    ctx.arcTo(x, y, x + r, y, r);
    ctx.closePath();
    }

    static drawPieChart(
    ctx: CanvasRenderingContext2D,
    cx: number, cy: number, radius: number,
    data: { label: string; value: number; color: string }[]
    ): void {
    const total = data.reduce((s, d) => s + d.value, 0);
    let startAngle = -Math.PI / 2;

    for (const item of data) {
    const angle = (item.value / total) * Math.PI * 2;
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    ctx.arc(cx, cy, radius, startAngle, startAngle + angle);
    ctx.closePath();
    ctx.fillStyle = item.color;
    ctx.fill();
    startAngle += angle;
    }
    }
    }

    10.2 使用示例

    // 初始化 Canvas 上下文
    const ctx = new CanvasRenderingContext2D();

    // 绘制圆角矩形
    CanvasUtil.drawRoundRect(ctx, 20, 20, 200, 100, 16);
    ctx.fillStyle = '#7B68EE';
    ctx.fill();

    // 绘制饼图
    CanvasUtil.drawPieChart(ctx, 200, 300, 80, [
    { label: '开心', value: 45, color: '#54A0FF' },
    { label: '温暖', value: 30, color: '#FF9F43' },
    { label: '感动', value: 25, color: '#FF6B9D' }
    ]);

    10.3 Canvas API 参考

    API功能性能影响
    beginPath 开始新路径
    arc 绘制圆弧
    fill 填充路径
    drawImage 绘制图像
    clip 裁剪区域

    Canvas 优化:避免在每一帧都重新绘制静态内容,使用离屏 Canvas 缓存可以提高绘制性能。

    总结

    // Canvas 绘制示例
    private context: CanvasRenderingContext2D;

    function draw(): void {
    this.context.beginPath();
    this.context.moveTo(50, 50);
    this.context.lineTo(200, 150);
    this.context.stroke();
    }

    本文深入解析了 Canvas 画布的基础用法。核心要点如下:

  • Canvas 组件:声明画布,传入 CanvasRenderingContext2D 对象
  • 坐标系统:原点在左上角,X 向右,Y 向下
  • 路径绘制:beginPath、moveTo、lineTo、arc、stroke、fill
  • onReady 回调:在组件就绪后执行绘制
  • 如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


    // 数据绑定示例
    @Entry
    @Component
    struct DataBinding {
    @State message: string = "Hello HarmonyOS";

    build() {
    Column() {
    Text(this.message)
    .fontSize(20)
    .fontColor("#7B68EE")
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
    }
    }

    // 条件渲染示例
    @State isVisible: boolean = false;

    build() {
    Column() {
    if (this.isVisible) {
    Text("内容可见")
    .fontSize(16)
    }
    Button("切换")
    .onClick(() => {
    this.isVisible = !this.isVisible;
    })
    }
    }

    九、完整示例代码

    9.1 完整组件实现

    以下是一个完整的组件实现示例,展示了本文介绍的各个技术点的综合运用:

    import { Component, State, Prop } from '@kit.ArkUI';

    @Component
    export struct DemoComponent {
    @Prop title: string = '';
    @State count: number = 0;

    build() {
    Column({ space: 12 }) {
    // 标题区域
    Text(this.title)
    .fontSize(18)
    .fontWeight(FontWeight.Bold)
    .fontColor('#1A1A2E')
    .width('100%')

    // 内容区域
    Text(`当前计数: ${this.count}`)
    .fontSize(14)
    .fontColor('#6B7280')

    // 交互按钮
    Button('点击增加')
    .width(120)
    .height(40)
    .backgroundColor('#7B68EE')
    .borderRadius(20)
    .fontColor(Color.White)
    .onClick(() => {
    this.count++;
    })
    }
    .width('100%')
    .padding(16)
    .backgroundColor(Color.White)
    .borderRadius(12)
    .shadow({ radius: 4, color: '#00000008', offsetX: 0, offsetY: 2 })
    }
    }

    9.2 使用方式

    在页面中引入并使用该组件:

    @Entry
    @Component
    struct Index {
    build() {
    Column() {
    DemoComponent({ title: '示例组件' })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F8F9FA')
    }
    }

    9.3 代码说明

    • 组件封装:使用 @Component 装饰器定义可复用的组件
    • 状态管理:使用 @State 管理组件内部状态
    • 参数传递:使用 @Prop 接收外部传入的参数
    • 事件处理:使用 onClick 处理用户交互
    • 样式优化:使用 borderRadius、shadow 等属性美化 UI

    相关资源:

    • 官方文档 – 开发者指南:HarmonyOS 应用开发
    • 官方文档 – ArkUI 组件参考:ArkUI 组件
    • 官方文档 – API 参考:API 参考
    • 官方文档 – 状态管理:状态管理概述
    • 官方文档 – 动画:动画概述
    • 官方文档 – 网络管理:网络管理
    • 官方文档 – 数据管理:数据管理
    • 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
    赞(0)
    未经允许不得转载:171主机测评 » HarmonyOS应用开发实战:小事记 - Canvas 画布基础:CanvasRenderingContext2D 的路径绘制与坐标系统
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址