这是之前写过的一个项目,后来删掉了,现在适配到api12重新发布,友友们按需查阅。

本文主要通过抽奖转盘小项目讲解在鸿蒙开发中如何使用画布组件Canvas绘制图形和文字,以及转圈动画的实现。效果图如下:

首先绘制转盘的六个分区:

drawInnerArc() {
let colors = [
'rgb(61,127,255)','rgb(121,189,255)'
];
let radius = this.screenWidth * 0.336;
for (let i = 0; i < 6; i++) {
if (this.canvasContext !== undefined) {
this.canvasContext.beginPath();
this.canvasContext.fillStyle = colors[i%2];
this.canvasContext.arc(0, 0, radius,
this.startAngle * Math.PI / 180, (this.startAngle + this.avgAngle) * Math.PI / 180);
this.canvasContext.fill();
}
this.canvasContext?.lineTo(0, 0);
this.canvasContext?.fill();
this.startAngle += this.avgAngle;
}
}

在界面中添加画布组件,将转盘区域绘制出来:

Canvas(this.canvasContext)
.width('100%')
.height('100%')
.onReady(() => {
this.drawModel.draw(this.canvasContext, this.screenWidth, this.screenHeight);
})

然后在转盘的分区上分别绘制文字,注意,这里的文字使用Text组件并不容易实现,因为要进行角度的调整,使每个文字都朝向圆心的位置:

let textArrays = [
"玉米","番茄","西瓜","苹果","樱桃","菠萝"
]; let arcTextStartAngle = 34;
let arcTextEndAngle = 26;
for (let i = 0; i < 6; i++) { let startAngle = (this.startAngle + arcTextStartAngle) * Math.PI / 180
let endAngle = (this.startAngle + arcTextEndAngle) * Math.PI / 180 class CircleText {
x: number = 0;
y: number = 0;
radius: number = 0;
}
let circleText: CircleText = {
x: 0,
y: 0,
radius: this.screenWidth * 0.336
};
// The radius of the circle.
let radius = circleText.radius - circleText.radius / 6;
// The radians occupied by each letter.
let angleDecrement = (startAngle - endAngle) / (textArrays[i].length - 1);
let angle = startAngle;
let index = 0;
let character: string; while (index < textArrays[i].length) {
character = textArrays[i].charAt(index);
this.canvasContext?.save();
this.canvasContext?.beginPath();
this.canvasContext?.translate(circleText.x + Math.cos(angle) * radius,
circleText.y - Math.sin(angle) * radius);
this.canvasContext?.rotate(Math.PI / 2 - angle);
this.canvasContext?.fillText(character, 0, 0);
angle -= angleDecrement;
index++;
this.canvasContext?.restore();
} this.startAngle += this.avgAngle;
}

此时一个基本的转盘已经完成了,可以在转盘外增加一个大转盘作为修饰:

drawOutCircle() {
// Draw outer disc.
this.fillArc(new FillArcData(0, 0, this.screenWidth * 0.4, 0,
Math.PI * 2), 'rgb(102,177,255)'); let beginAngle = this.startAngle;
// Draw small circle.
for (let i = 0; i < 8; i++) {
this.canvasContext?.save();
this.canvasContext?.rotate(beginAngle * Math.PI / 180); if (this.canvasContext !== undefined) {
this.canvasContext.beginPath();
this.canvasContext.fillStyle = '#FFFFFF';
this.canvasContext.arc(this.screenWidth * 0.378, 0, 4.1,
0, 360);
this.canvasContext.fill();
} beginAngle = beginAngle + 360 / 8;
this.canvasContext?.restore();
}
}

使用叠加布局为转盘添加指针:

Stack({ alignContent: Alignment.Center }) {
Canvas(this.canvasContext)
.width('100%')
.height('100%')
.onReady(() => {
this.drawModel.draw(this.canvasContext, this.screenWidth, this.screenHeight);
})
.rotate({
x: 0,
y: 0,
z: 1,
angle: this.rotateDegree,
centerX: this.screenWidth / 2,
centerY: this.screenHeight / 2
}) Image($r('app.media.btn_start'))
.width('19.3%')
.height('10.6%')
.enabled(this.enableFlag) }

好了,界面大功告成。接下来是动画部分,我们可以给指针添加一个点击事件,为转盘添加旋转动画:

startAnimator() {
let randomAngle = Math.round(Math.random() * 360); animateTo({
duration: 4000,
curve: Curve.Ease,
delay: 0,
iterations: 1,
playMode: PlayMode.Normal,
onFinish: () => {
this.rotateDegree = 270 - randomAngle;
}
}, () => {
this.rotateDegree = 360 * 5 +
270 - randomAngle;
})
}
Image($r('app.media.btn_start'))
.width('19.3%')
.height('10.6%')
.enabled(this.enableFlag)
.onClick(() => {
this.enableFlag = !this.enableFlag;
this.startAnimator();
})

以上就是整个转盘的开发过程.

HarmonyOS NEXT开发实战案例--抽奖转盘的更多相关文章

  1. Android SurfaceView实战 打造抽奖转盘

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41722441 ,本文出自:[张鸿洋的博客] 1.概述 今天给大家带来Surfac ...

  2. Hadoop应用开发实战案例 第2周 Web日志分析项目 张丹

    课程内容 本文链接: 张丹博客 http://www.fens.me 用Maven构建Hadoop项目 http://blog.fens.me/hadoop-maven-eclipse/程序源代码下载 ...

  3. 015_[小插曲]看黄老师《炼数成金Hadoop应用开发实战案例》笔记

    1.大数据金字塔结构 Data Source-->Data Warehouses/Data Marts-->data exploration-->Data Mining-->D ...

  4. Hadoop应用开发实战案例 第2周

    比如,封面,是一网页,可以看出用户在此网页上,鼠标呈现F形状. 海量Web日志分析 用Hadoop提取KPI统计指标 更详细原文博客:http://blog.fens.me/hadoop-mapred ...

  5. Hadoop应用开发实战案例 第1周

    本课程的基础课程是,Hadoop数据分析平台课程.相信,能看我本博文的朋友,是有一定的基础了. 只是前个课程是讲解,这个课程是应用. 第一层是:数据源层,代表有生产线上的数据,比如关系型数据库orca ...

  6. 第15.25节 PyQt(Python+Qt)入门学习:Model/View开发实战--使用QTableView展示Excel文件内容

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 在前面的订阅专栏<第十九章.Model/View开发:QTableView的功能及属 ...

  7. 【Vue.js实战案例】- Vue.js递归组件实现组织架构树和选人功能

    大家好!先上图看看本次案例的整体效果. 浪奔,浪流,万里涛涛江水永不休.如果在jq时代来实这个功能简直有些噩梦了,但是自从前端思想发展到现在的以MVVM为主流的大背景下,来实现一个这样繁杂的功能简直不 ...

  8. 《Spring 3.x 企业应用开发实战》目录

    图书信息:陈雄华 林开雄 编著 ISBN 978-7-121-15213-9 概述: 第1章:对Spring框架进行宏观性的概述,力图使读者建立起对Spring整体性的认识. 第2章:通过一个简单的例 ...

  9. [置顶] PHP开发实战权威指南-读书总结

    从今年开始,断断续续学习PHP已经有4个月了. 最初,认真学习PHP几天,就弄WordPress搭建了一个个人博客,这也符合技术人的实践理念. 最近,重温PHP开发实战权威指南,做点总结,整理下自己学 ...

  10. Hadoop应用开发实战(flume应用开发、搜索引擎算法、Pipes、集群、PageRank算法)

    Hadoop是2013年最热门的技术之一,通过北风网robby老师<深入浅出Hadoop实战开发>.<Hadoop应用开发实战>两套课程的学习,普通Java开发人员可以在最快的 ...

随机推荐

  1. Github 访问失败,问题修复

    参考学习链接: https://www.cnblogs.com/MuQuanyu-YuGod/articles/12549766.html Github 网站无法访问的解决方法: 解决方案: Cd到文 ...

  2. 泰山派linux(Ubuntu 20.04)安装GCC编译环境

    linux(Ubuntu 20.04)安装gcc编译环境 1.查看可安装的编译链版本(在用户apt软件源中检索) apt-cache search aarch64 交给AI翻译 后面验证得知本版本Ub ...

  3. Postman 调试 SignalR 发布的wss接口

    微软官网的SignalR例子拿来跑即可 Postman 调试SignalR 发送post请求获取token 将获取到的connectionToken加入ws链接 点击 Connect 发送第一条协商消 ...

  4. JUC并发—12.ThreadLocal源码分析

    大纲 1.ThreadLocal的特点介绍 2.ThreadLocal的使用案例 3.ThreadLocal的内部结构 4.ThreadLocal的核心方法源码 5.ThreadLocalMap的核心 ...

  5. 大数据之路Week10_day05 (JavaAPI 操作Redis 第一阶段)

    刚开始学习JavaAPI的时候,主要是对redis中的字符串,字节位图,列表,集合,有序集合进行操作,并能够完成简单的需求. package com.wyh.redis; import org.jun ...

  6. 『Python底层原理』--Python字符串的秘密

    在现代编程中,字符串是不可或缺的数据类型. 无论是处理用户输入.文件读写还是网络通信,字符串都扮演着核心角色. 然而,字符串的处理并非简单地将字符拼接在一起,它涉及到字符集.编码以及编程语言的底层实现 ...

  7. C#/.NET/.NET Core技术前沿周刊 | 第 28 期(2025年2.24-2.28)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  8. Fermat

    [KPCTF 2024]ez_fermat from Crypto.Util.number import * p = getPrime(1024) q = getPrime(813) n = p * ...

  9. job提交后,inp文件的处理过程

    用户提交job后,abaqus的inp文件处理过程 1. 对inp文件预处理 打开任务管理器可以看到pre.exe的进程 预处理中的error .warning 都会在.DAT文件中 dat文件出现e ...

  10. SQL注入之WAF绕过注入

    绕过WAF: WAF防御原理: 简单来说waf就是解析http请求,检测http请求中的参数是否存在恶意的攻击行为,如果请求中的参数和waf中的规则库所匹配,那么waf则判断此条请求为攻击行为并进行阻 ...