自定义人员抽签工具(ArkTS)v6.0

介绍

本篇Codelab是基于画布组件、显式动画,实现的一个自定义人员抽签工具。该版本(v6.0)在原有转盘功能基础上进行了全面升级,重点增强了交互性和扩展性,主要用于随机抽取人员(如年会抽奖、活动点名等场景)。

主要功能亮点:

  1. 自定义名单抽签:支持用户在界面直接输入6位人员姓名,实时生成专属抽签转盘。
  2. 可视化随机抽取:通过Canvas绘制动态转盘,结合显式动画实现流畅的随机抽签过程。
  3. 结果弹窗展示:抽签结束后,自动弹出中签人员信息。
  4. 支持二次开发:代码结构模块化设计,清晰分离视图、模型与常量,方便开发者根据需求进行二次修改(如调整人数上限、UI样式、中奖逻辑等)。
    在这里插入图片描述

相关概念

  • Stack组件:堆叠容器,用于实现转盘背景、画布与指针的层叠布局。
  • Canvas:核心绘图组件,用于动态绘制包含自定义姓名的转盘。
  • CanvasRenderingContext2D:提供2D绘制能力,实现扇形、文字、图片的绘制。
  • 显式动画:使用 animateTo 实现转盘的加减速旋转效果。
  • 自定义弹窗: 用于展示最终的抽签结果。

模块化接口迁移 (Kit Migration)

针对 OpenHarmony 6.0 推出的系统能力模块化 (System Capability Kits),对项目中的核心引用库进行了标准化的替换,摒弃了旧版 @ohos.* 的导入方式,全面拥抱 @kit.* 规范:

功能模块 旧版接口 (Deprecated) 新版接口 (API 20 Adapted)
日志系统 @ohos.hilog @kit.PerformanceAnalysisKit
Ability能力 @ohos.app.ability.UIAbility @kit.AbilityKit
窗口管理 @ohos.window @kit.ArkUI
矩阵变换 @ohos.matrix4 @kit.ArkUI
路由跳转 @ohos.router @kit.ArkUI

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 6.0 Release及以上。
  • OpenHarmony SDK版本:API version 20。

硬件要求

环境搭建步骤

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。
  2. 搭建烧录环境。
    1. 完成DevEco Device Tool的安装
    2. 完成RK3568开发板的烧录
  3. 搭建开发环境。
    1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
    3. 工程创建完成后,选择使用真机进行调测

代码结构与二次开发指南

本工具代码结构清晰,开发者可轻松进行二次修改。

├──entry/src/main/ets	            // 代码区
│  ├──common
│  │  ├──constants
│  │  │  ├──ColorConstants.ets      // 颜色常量:可修改转盘颜色、文字颜色
│  │  │  ├──CommonConstants.ets     // 公共常量:可修改转盘分区数量(COUNT)、动画时长(DURATION)等
│  │  │  └──StyleConstants.ets      // 样式常量:可修改组件尺寸、边距
│  │  └──utils
│  │     ├──CheckEmptyUtils.ets     // 工具类
│  │     └──Logger.ets              // 日志类
│  ├──entryability
│  │  └──EntryAbility.ts            // 入口
│  ├──pages
│  │  └──CanvasPage.ets             // 主界面:包含UI布局和交互逻辑	
│  ├──view
│  │  └──PrizeDialog.ets            // 结果弹窗:可自定义弹窗样式
│  └──viewmodel
│  │     ├──DrawModel.ets              // 核心绘制逻辑:修改 draw 方法可调整转盘样式
│  │     ├──FillArcData.ets            // 实体类
│  │     └──PrizeData.ets              // 实体类
│  └──entry/src/main/resources         // 资源文件:图片、字符串资源

二次开发建议

  • 修改人数/分区数:修改 CommonConstants.ets 中的 COUNT 常量,并同步更新 DrawModel.ets 中的绘制逻辑和颜色分配。
  • 修改转盘配色:在 ColorConstants.ets 中调整配色方案。
  • 修改交互逻辑:在 CanvasPage.ets 中修改按钮点击事件和输入逻辑。

构建主界面

在这个章节中,我们将完成示例主界面的开发。主界面主要包含两部分:

  1. 抽签转盘区域:使用Canvas组件绘制,支持自定义姓名显示。
  2. 控制区域:包含输入框和按钮,用于设置参与抽签的人员名单。

效果如图所示:

在这里插入图片描述

核心实现逻辑

  1. 获取屏幕宽高:在aboutToAppear中获取屏幕尺寸,用于适配Canvas绘制。
  2. 动态名单录入
    • 提供 TextInput 组件接收用户输入的姓名(以空格分隔)。
    • 点击“提交”按钮后,解析姓名字符串为数组 names
    • 通过改变 @State canvasKey 强制触发 Canvas 组件的 onReady 回调,从而重绘转盘。
  3. Canvas绘制DrawModel 根据最新的 names 数组,动态计算并绘制每个扇区的文字。
// CanvasPage.ets

@Entry
@Component
struct CanvasPage {
  // ... 其他状态变量
  @State nameText: string = "张三 李四 王五 六六 七七 八八"; // 默认名单
  @State names: string[] = ['一', '二', '三', '四', '五', '六'];
  @State canvasKey: number = 0; // 用于强制 Canvas 重新渲染

  build() {
    Stack({ alignContent: Alignment.Center }) {
      // 1. 转盘画布
      Canvas(this.canvasContext)
        .key(this.canvasKey.toString()) // 关键:key变化触发重绘
        .onReady(() => {
          // 传入自定义名单进行绘制
          this.drawModel.draw(this.canvasContext, this.screenWidth, this.screenHeight, this.names);
        })
        .rotate({ /* 旋转配置 */ })

      // 2. 中心指针与控制区
      Column({ space: 200 }) {
         // ... 顶部图片
         
         // 启动按钮
         Image($r('app.media.ic_center'))
           .onClick(() => {
             this.startAnimator(); // 开始抽签动画
           })

         // 底部输入控制区
         Column({ space: 5 }) {
           Row({ space: 20 }) {
             TextInput({ placeholder: "请输入姓名" })
               .onChange((value: string) => {
                 this.nameText = value;
               })
             
             Button("提交")
               .onClick(() => {
                 // 解析输入并重绘
                 this.names = this.nameText.split(" ");
                 this.canvasKey++; // 触发重绘
                 this.updateCanvas();
               })
           }
           Text("*请输入姓名,姓名用空格隔开,必须是6个人")
         }
      }
    }
  }
}

绘制逻辑 (DrawModel)

DrawModel类负责具体的Canvas绘制操作,draw方法接收names数组并在扇形区域绘制对应的文字。

// DrawModel.ets
export default class DrawModel {
  // ...
  
  draw(canvasContext: CanvasRenderingContext2D, screenWidth: number, screenHeight: number, names: string[]) {
    // ... 清除画布与坐标变换
    
    // 更新名称,支持自定义
    this.name1 = names[0];
    this.name2 = names[1];
    // ...
    this.name6 = names[5];

    // 绘制各个部分
    this.drawFlower();      // 外圈花瓣
    this.drawOutCircle();   // 外圈圆
    this.drawInnerCircle(); // 内圈圆
    this.drawInnerArc();    // 内部扇形
    this.drawArcText();     // 绘制自定义姓名
    this.drawImage();       // 奖品图片
  }
}

总结

通过本Codelab,我们实现了一个功能完备的自定义人员抽签工具。项目展示了如何利用 ArkTS 的 Canvas 组件进行动态内容绘制,以及如何通过状态管理实现用户输入与界面更新的实时交互。同时,模块化的代码结构也为开发者提供了良好的二次开发基础。

https://gitcode.com/MakerStudio/HM_CanvasComponent

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐