这是之前写过的一个项目,后来删掉了,现在适配到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. Hadoop应用开发实战案例 第2周 Web日志分析项目 张丹

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. [原创].NET 分布式架构开发实战之二 草稿设计

    原文:[原创].NET 分布式架构开发实战之二 草稿设计 .NET 分布式架构开发实战之二 草稿设计 前言:本篇之所以称为草稿设计,是因为设计的都是在纸上完成的.反映了一个思考的过程. 本篇的议题如下 ...

  10. AI应用开发实战 - 手写识别应用入门

    AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...

随机推荐

  1. 从0搭建Vue3组件库(一): 开篇

    前言 这是从0搭建Vue3组件库系列文章第一篇文章,这个系列我曾经写过多篇文章,但是写完之后回过头来再看里面有很多遗漏以及不足之处,所以决定重新梳理这个系列,并从头开始搭建一个完整的Vue3组件库工程 ...

  2. GIT如何进行团队协作

    加入其他开发成员.修改代码并提交 选择库点击管理 点击添加成员邀请用户 以下三种方式都行 加入后如下 第二人如何进行修改文件: 在文件夹中创建本地库git init 建立远程连接 git remote ...

  3. Twain Capabilities属性

    Asynchronous Device Events 异步设备事件 CAP_DEVICEEVENT MSG_SET选择应用程序希望Twain源报告的事件; MSG_RESET返回Twain源的首选设置 ...

  4. Web前端入门第 10 问:HTML 段落标签( <p> )嵌套段落标签( <p> )的渲染结果会怎样?

    HELLO,这里是大熊学习前端开发的入门笔记. 本系列笔记基于 windows 系统. 曾经有一个神奇的 bug 摆在我面前,为什么套娃一样的 HTML 语法,在段落标签 <p> 身上不生 ...

  5. Xshell连接VirtualBox虚拟机中的CentOS

    前提: 安装好VirtualBox虚拟机,并且在虚拟机上安装好CentOS系统. 具体步骤: 1.进入CentOS虚拟机设置--网络--高级--端口转发 2.新增端口规则,按照下面图片填写. 3.打开 ...

  6. 初识 PHP 7 源码整体框架

    目录 PHP 7 语言的执行原理 编译型语言与解释型语言 PHP 7 语言的执行原理 我们常用的高级语言有很多种,比较出名的有C\C++.Python.PHP.Go.Pascal等.而这些语言根据运行 ...

  7. Thinkphp3.2 PHPMailer 发送邮件

    第一步 :下载附件PHPMailer解压到ThinkPHP\Library\Vendor 第二步:在Common文件夹中的公共函数function.php中写一个发送邮件的函数, 这样可以在项目任意位 ...

  8. 区块链特辑——solidity语言基础(五)

    Solidity语法基础学习 九.实战项目(一): 学以致用 UP主捐款合约 ·合约要求: ·建立时,需将合约的建立者设定成owner(constructor,msg.sender) ·需记录每个观众 ...

  9. String类的三种常见构造方法

    1.根据构造方法创建字符串对象 1.public String() 创建一个空字符串,里面不包含任何内容 2.public String(char[] chs) 创建一个字符数组,将其拼接成字符串对象 ...

  10. 【Python】PDF文档导出指定章节为TXT

    PDF文档导出指定章节为TXT 需求 要导出3000多个pdf文档的特定章节内容为txt格式(pdf文字可复制). 解决 导出PDF 查了一下Python操作PDF文档的方法,主要是通过3个库,PyP ...