Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第7章:高级UI组件与自定义绘制

第7章:高级UI组件与自定义绘制

Canvas绘图

7.3.1 Canvas基础概念

ArkTS中的Canvas组件提供了一块可自由绘制的画布,开发者可以通过它实现复杂的图形绘制、自定义图表、游戏画面等高级UI效果。Canvas的核心特点包括:

  1. 坐标系系统:基于左上角原点(0,0)的二维坐标系
  2. 绘图上下文:通过getContext('2d')获取2D渲染上下文对象
  3. 即时模式:所有绘制操作会立即反映在画布上

7.3.2 基本绘图API

路径绘制

// 示例:绘制三角形路径
Canvas({ width: 200, height: 200 })
  .onReady((ctx: CanvasRenderingContext2D) => {
    ctx.beginPath()
    ctx.moveTo(100, 20)
    ctx.lineTo(20, 180)
    ctx.lineTo(180, 180)
    ctx.closePath()
    ctx.stroke()
  })

形状绘制

  • fillRect(x, y, width, height):填充矩形
  • strokeRect():描边矩形
  • arc(x, y, radius, startAngle, endAngle):绘制圆弧

样式控制

ctx.fillStyle = '#FF0000'  // 设置填充色
ctx.strokeStyle = '#00FF00' // 设置描边色
ctx.lineWidth = 5          // 设置线宽

7.3.3 高级绘图技术

图像处理

// 加载并绘制图像
Image('resources/image.png')
  .onLoad((img: ImageBitmap) => {
    ctx.drawImage(img, 0, 0, 200, 200)
  })

变换操作

ctx.save()          // 保存当前状态
ctx.translate(100, 100) // 移动原点
ctx.rotate(Math.PI/4)   // 旋转45度
ctx.scale(1.5, 1.5)     // 缩放
ctx.restore()       // 恢复之前保存的状态

动画实现

@State angle: number = 0

Canvas({ width: 200, height: 200 })
  .onReady((ctx) => {
    setInterval(() => {
      this.angle += 0.1
      ctx.clearRect(0, 0, 200, 200)
      ctx.save()
      ctx.translate(100, 100)
      ctx.rotate(this.angle)
      ctx.fillRect(-25, -25, 50, 50)
      ctx.restore()
    }, 16) // ~60fps
  })

7.3.4 性能优化建议

  1. 分层绘制:将静态内容和动态内容分离到不同Canvas
  2. 脏矩形技术:只重绘发生变化的部分区域
  3. 避免频繁创建对象:复用Path2D对象
  4. 使用离屏Canvas:预渲染复杂图形

7.3.5 实战案例:绘制动态折线图

@Component
struct LineChart {
  @State data: number[] = [20, 45, 28, 80, 50]
  
  build() {
    Canvas({ width: 300, height: 200 })
      .onReady((ctx) => {
        // 绘制坐标轴
        ctx.strokeStyle = '#666'
        ctx.beginPath()
        ctx.moveTo(30, 180)
        ctx.lineTo(270, 180)
        ctx.moveTo(30, 180)
        ctx.lineTo(30, 20)
        ctx.stroke()
        
        // 绘制折线
        ctx.strokeStyle = '#1E90FF'
        ctx.lineWidth = 2
        ctx.beginPath()
        this.data.forEach((value, index) => {
          const x = 30 + index * 60
          const y = 180 - value * 2
          if (index === 0) {
            ctx.moveTo(x, y)
          } else {
            ctx.lineTo(x, y)
          }
        })
        ctx.stroke()
      })
  }
}

最佳实践提示:对于复杂的数据可视化需求,建议封装可复用的图表组件,通过属性绑定实现数据驱动更新。

Last Updated:: 5/22/25, 5:00 PM