您现在的位置是:亿华云 > 系统运维
OpenHarmony ArkUI+原生绘图之幸运大转盘
亿华云2025-10-09 06:58:03【系统运维】2人已围观
简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com效果展示此外,转盘的奖项的数量,内容都是可以变动的(菜单就是用来编辑奖项的,后续完善),如
想了解更多内容,原生运请访问:
和华为官方合作共建的绘图鸿蒙技术社区
https://harmonyos.51cto.com
效果展示

此外,转盘的幸转盘奖项的数量,内容都是原生运可以变动的(菜单就是用来编辑奖项的,后续完善),绘图如下:

主要功能
实现转盘抽奖功能,幸转盘可以设定中奖概率。原生运 奖项的绘图数量、内容可自由设定。幸转盘 原生html\css\js代码,原生运没有使用资源文件,绘图可复用。幸转盘设计时考虑到的原生运问题
1.控件是使用现有图片还是通过CSS画出?
先是用的图片充当控件,考虑到奖项的绘图内容可编辑性,还是幸转盘老老实实画控件比较好。
2.每个奖项的概率如何设计?
先生成一个随机数,根据随机数取值大小,决定奖品内容。云服务器假设所有奖项的取值范围坐落到0100的数轴上,并且1号奖品的取值范围是010,2号:10~30, 3号:30~35,。。。通过设定每个奖项取值区间的大小来决定中奖的权重,这样就能控制中奖概率了。
3.如何实现奖项可编辑?
我将所有奖项存放在一个数据数组中,先能通过遍历数组中奖项信息,画出转盘,这是第一步。
之后,通过菜单功能提供一个列表控件,使其能够对数组中的信息进行增删改查,这是第二步。
在界面加载的onShow()函数中进行初始化,这样每次界面显示的时候就能更新转盘了。
具体代码
index.hml
<div class="container"> <text class="title"> 幸运大转盘 </text> <div class="outer" id="outer"> <!--画布--> <canvas id="canvas" class="canvas"></canvas> <!--内圆--> <div class="circle"></div> <!--长方形--> <div class="rectangle"></div> <!--正方形箭头--> <div class="square"></div> </div> <div class="btns"> <button class="button" type="capsule" onclick="start"> 抽奖 </button> <button class="button" type="capsule" onclick="menu"> 菜单 </button> </div> </div>outer就是转盘整体,包含转盘和箭头。源码库我箭头是通过将圆+长方形+正方形平移、旋转组合而成的(虽然有点笨,没有想到其它办法)。转盘是一个画布canvas,通过移动画笔起点,旋转,一个扇区接一个扇区画出的。按键有两个,抽奖就是转动转盘,实现抽奖逻辑。菜单按键跳转到新的界面,实现奖项内容的编辑,当然还没写完。。。
index.css
.container { flex-direction: column; align-items: center; justify-content: space-between; } .title { font-size: 38px; font-weight: 600; height: 20%; } .outer { position: relative; } .canvas { width: 360px; height: 400px; } .circle { position: absolute; width: 40px; height: 40px; background-color: darkred; border-radius: 20px; transform: translate(160px,180px); } .rectangle { position: absolute; width: 20px; height: 40px; background-color: darkred; transform: translate(170px,150px); } .square { position:absolute; width: 20px; height: 20px; background-color: darkred; top: 140px; left: 170px; transform: rotate(45deg); } .btns { justify-content:space-around; } .button{ margin-top: 10%; height: 10%; font-size: 30px; font-weight: 600; }canvas中的宽、高决定了转盘大小,代码中将转盘的半径设置为画布一半宽的长度。同时,由于箭头是由圆、长方形、正方形平移旋转组成,亿华云计算那他们的偏移量、大小也是相对.canvas的属性取的,如果大小有变动需要调整。
为什么不将箭头也画出来?
如果将箭头也画在画布上,那么我不能实现转盘转动,箭头不动的动画了,画布是一个整体。
index.js
import prompt from @system.prompt; import router from @system.router; export default { data: { //1.1创建奖项信息 infoArr: [ { name: 1号奖品 }, { name: 2号奖品 }, { name: 3号奖品 }, { name: 4号奖品 }, { name: 5号奖品 }, { name: 6号奖品 }, { name: 7号奖品 }, { name: 未中奖 }, ], //1.2画布大小 circleHeight: 400, circleWidth: 360, //1.3扇区弧度 arcAngle: 0, //1.4扇区角度 jiaoDu: 0, //1.4动画参数 animation: , options: { duration: 5000, fill: forwards, easing: cubic-bezier(.2,.93,.43,1);, }, }, onShow() { const ca = this.$element(canvas); const ctx = ca.getContext(2d); //2.设定参数 //2.1定义圆心,显示在画布中间 var x0 = this.circleWidth * 0.5; var y0 = this.circleHeight * 0.5; //2.2定义半径 var radius = this.circleWidth * 0.5; //2.3扇形弧度 this.arcAngle = 360 / this.infoArr.length * Math.PI / 180; //2.4扇区角度 this.jiaoDu = 360 / this.infoArr.length; //2.5定义起始弧度,箭头向上,初始度数需要-90deg var beginAngle = this.arcAngle * 0.5 - 90 * Math.PI / 180; //3.遍历,绘制扇区 for (var i = 0; i < this.infoArr.length; i++) { //3.1结束弧度 var endAngle = beginAngle + this.arcAngle; //3.2开启路径 ctx.beginPath(); //3.3起点 ctx.moveTo(x0, y0); //3.4绘制扇区 ctx.arc(x0, y0, radius, beginAngle, endAngle); //3.5设置颜色 if (i == this.infoArr.length - 1) { ctx.fillStyle = #2f4f4f; //未中奖灰色 } else if (i % 2) { ctx.fillStyle = #ffa500; } else { ctx.fillStyle = #ff4500; } //3.6填充颜色 ctx.fill(); //4.绘制文字 //4.1文字弧度 var textAngle = beginAngle + this.arcAngle * 0.5; var text = this.infoArr[i].name; //4.2文字坐标 var textX = x0 + (radius * 2 / 3) * Math.cos(textAngle); var textY = y0 + (radius * 2 / 3) * Math.sin(textAngle); //4.3平移画布起点到文字位置 ctx.translate(textX, textY); //4.4旋转画布 ctx.rotate((this.jiaoDu * (i + 1) - 90) * Math.PI / 180); //4.5设置文字字号和字体 ctx.font = "25px 微软雅黑"; //4.6文字居中对齐 ctx.textAlign = center; ctx.textBaseline = middle; //4.7绘制文字 ctx.strokeText(text, 0, 0); //4.8还原旋转、平移,方便下次旋转 ctx.rotate(-(this.jiaoDu * (i + 1) - 90) * Math.PI / 180); ctx.translate(-textX, -textY); //5.更新起始弧度, 将当前扇形的结束弧度作为下一个扇形的起始弧度 beginAngle = endAngle; } }, start: function () { //6.旋转事件 //6.1奖品总数 let count = this.infoArr.length; //6.2生成随机数 let randomNum = Math.floor(Math.random() * count); //6.3转动角度(+ 360*3) let deg = randomNum * this.jiaoDu + 360 * 3 + "deg"; //6.4奖品名 let index = count - randomNum - 1; let name = this.infoArr[index].name; console.log("name == " + name); //6.5动画帧 var frames = [ { transform: { rotate: 0deg }, }, { transform: { rotate: deg }, } ]; //6.5动画绑定 this.animation = this.$element(canvas).animate(frames, this.options); //6.6添加完成事件 this.animation.onfinish = function () { if (randomNum % count) { prompt.showDialog({ message: "恭喜抽中" + name + "!" }); } else { prompt.showDialog({ message: "下次再来!" }); } }; //6.7调用播放开始的方法 this.animation.play(); }, menu: function () { router.push ({ uri: pages/menuPage/menuPage, }); }, }js中存放主要逻辑,所以对注释也比较详细。下面是个人踩坑中学习的点:
//1.1创建奖项信息 可以增加减少奖项来预览将要实现的菜单功能,不要搞事情哈,奖项至少为1,代码中没有除0保护。 //1.4动画参数 duration是时长。easing,是描述动画的时间曲线,实现动画由快变慢。fill:forwards在动画结束后,目标将保留动画结束时的状态。 //3.4绘制扇区 x0, y0,扇区的起点坐标。radius,扇区半径。beginAngle,扇区起始的弧度,endAngle,扇区结束的弧度。 //3.5设置颜色 每个扇区设置两个相间的颜色,未中奖特殊扇区用灰色调标识。 //4.2文字坐标 由于文字在扇区中间,所以需要利用正弦余弦计算坐标,再进行画面旋转,才能调整正确的文字方向。 //4.8还原旋转、平移,方便下次旋转 translate函数是基于当前坐标进行偏移,旋转也是基于当前坐标进行旋转。所以当一个扇区的文字填写结束后,需要将坐标还原,这样才方便定位到一下处扇区位置。想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com
很赞哦!(636)
相关文章
- 比较短的域名方便用户记忆和传播,它带来的好处往往会超过其他类型的域名,如果你非要域名短而且还要包含关键词,那么往往会事与愿违,现在这种域名基本上是可遇而不可求的。
- 英伟达切入300亿美元的定制芯片市场,应对博通Marvell等对手挑战
- Ampere 年度展望:2025年重塑IT格局的四大关键趋势
- 如何设计一个有效的数据中心电缆标签系统
- tk域名是什么域名?新手对tk域名有什么看法?
- KADC 2025 东方通与鲲鹏深化合作 共筑RAG解决方案与出海新生态
- 五种使用Nginx作为负载均衡器的实用方法
- 五大重磅提升 联想问天首款AMD机型WR5225 G3震撼上市
- 什么是im域名?新手需要了解im域名哪些?
- 开源的DNS服务BIND完全解析,你学会了吗?
站长推荐
域名不仅仅是一个简单的网站。对于有长远眼光的公司来说,在运营网站之前确定一个优秀的域名对有长远眼光的公司来说是非常重要的。这对今后的市场营销、产品营销和企业品牌建设都具有十分重要的意义。优秀的域名是企业在市场竞争中获得持久优势的利器。
微软发布量子芯片Majorana 1:看好量子计算“未来数年内实现”
权衡数据中心层级系统的利与弊
网页无法加载?原来是服务器被洪水冲垮了
为什么起域名意义非凡?起域名有什么名堂?
鲲鹏开发者峰会2025:面向AI场景,鲲鹏为开发者提供全套鲲鹏AI+解决方案
英特尔CEO炮轰英伟达:CUDA技术已过时,整个产业都想终结它
破解大模型算力天花板,昇腾大EP推理方案推动AI进入千行百业