引言
身为一个前端开发,老板说让我去学鸿蒙开发
好好好 这么好的机会我不得好好抓住,我要去榨干鸿蒙开发同事的所有精华!!!
说干就干
需求
实现抽奖转盘转转转,
技术
我们就是代码的搬运工,ctrl+c 和ctrl+v是我们的吃饭技术,没到绝境是不可能用canvas直接手写的,更何况是我这种新手鸿蒙开发
上道具
开发工具:DevEco Studio
语言:ArkTS、ArkUI
插件工具:mpchart【openHarmony三方库中心仓】
开发三部曲
安装插件
ohpm install @ohos/mpchart
使用插件
1 引入相关依赖
import {
ChartColor,
ColorTemplate,
JArrayList,
MPPointF,
PieChart,
PieChartModel,
PieData,
PieDataSet,
PieEntry,
} from '@ohos/mpchart';
import animator, { AnimatorOptions, AnimatorResult } from '@ohos.animator';
2 界面展示-自定义
// 转盘显示
Row(){
Stack() {
Image($r('app.media.turn_table'))
.height('100%')
PieChart({ model: this.model })//转盘渲染在这里
.height('82%')
.aspectRatio(1)
Row(){
Stack(){
Image($r('app.media.turn_start'))
.width('80vp')
.height('80vp')
Text('开始')
.fontSize('14fp')
.fontColor(Color.White)
.margin({top:'14vp'})
}
}
.onClick(() => {
this.startGun();
})
}
}.height(380)
3 初始化转盘
@State model: PieChartModel = new PieChartModel();
@State animatorResult: AnimatorResult | null = null
@State onePartAngle: number = 0;//一扇的角度
@State totalCount:number = 0;//所有比值总和
//数据定义
@State parties:OptionSetting[]=[
new OptionSetting('麻辣火锅',1),
new OptionSetting('意大利披萨',1),
new OptionSetting('日式寿司',1),
new OptionSetting('中式快餐',1),
new OptionSetting('韩国烤肉',1),
new OptionSetting('素食沙拉',1),
]
@State count:number = this.parties.length
init() {
this.model.getDescription()?.setEnabled(false);
this.model.setDrawHoleEnabled(false);
this.model.getLegend()?.setEnabled(false);
this.model.disableScroll();
this.model.setHighlightPerTapEnabled(false);
this.model.setEntryLabelTextSize(14)
this.model.setEntryLabelColor(ColorTemplate.rgb('#606266'))
this.model.setTouchEnabled(true);
this.model.setRotationAngle(0); // 设置旋转角度
this.model.setUsePercentValues(true); // 使用百分比值
this.model.setDrawCenterText(true); // 绘制中心文本
// 通过触摸启用图表的旋转
this.model.setRotationEnabled(true);
this.setData(this.count);
}
// 初始化饼状图数据
async setData(range: number): Promise<void> {
let entries: JArrayList<PieEntry> = new JArrayList<PieEntry>();
// 先计算总和
for (let i = 0; i < this.count; i++) {
this.totalCount = this.totalCount + Number(this.parties[i].weight)
}
// NOTE: The order of the entries when being added to the entries array determines their position around the center of
// the chart.
for (let i = 0; i < this.count; i++) {
entries.add(new PieEntry( Number(this.parties[i].weight)*(360 / this.totalCount),this.parties[i].textVal,undefined,undefined));
}
let dataSet: PieDataSet = new PieDataSet(entries, "Election Results");
dataSet.setSliceSpace(0);
dataSet.setIconsOffset(new MPPointF(0, 40));
dataSet.setSelectionShift(5);
dataSet.setValueTextSize(12)
dataSet.setValueTextColor(ColorTemplate.rgb('#a8abb2'));
dataSet.setDrawValues(false);
// add a lot of colors
let colors: JArrayList<number> = new JArrayList();
for (let index = 0; index < ColorTemplate.COLORFUL_COLORS.length; index++) {
colors.add(ColorTemplate.COLORFUL_COLORS[index]);
}
// colors.add(ColorTemplate.getHoloBlue());
dataSet.setColorsByList(colors);
let data: PieData = new PieData(dataSet);
this.onePartAngle = 360 / this.totalCount;//一扇的角度
// this.model.setRotationAngle(-90 - this.onePartAngle / 2);
this.model.setData(data);
}
4 滚动操作
startGun() {
let chooseText = ''
let currentAngle = this.model.getRotationAngle(); //获取当前角度
let randomIndex: number = Math.floor(Math.random() * this.count);
let end = 7200 + randomIndex * currentAngle + this.onePartAngle; //随机生成滚动结束角度
let options: AnimatorOptions = {
duration: 5000,
easing: "ease",
delay: 0,
fill: "forwards",
direction: "normal",
begin: currentAngle,
end: end,
iterations: 1
};
this.animatorResult = animator.create(options)
this.animatorResult.onframe = (value) => {
this.model.setRotationAngle(value);
this.model.invalidate();
}
//滚动结束
this.animatorResult.onfinish = () => {
let endAngle = this.model.getRotationAngle()
// 渲染角度
for (let i = 0; i < this.parties.length; i++) {
const element = this.parties[i];
if(i==0){//算出第一个位置
element.angleX = Math.floor(endAngle*i + endAngle)
}else {
element.angleX = Number(this.parties[i-1].angleY)==360?0:Number(this.parties[i-1].angleY)
}
let RotateCicle:number = (element.angleX + this.onePartAngle * Number(element.weight))%360
element.angleY = (element.angleX + this.onePartAngle * Number(element.weight)) >= 360?RotateCicle :Math.floor((element.angleX + this.onePartAngle * Number(element.weight)))
if(element.angleX < element.angleY) {
if(270 >= element.angleX && 270 < element.angleY){
chooseText = element.textVal;
break;
}
}else {
if(270 >= element.angleX){
chooseText = element.textVal;
break;
}
}
}
if (this.dialogController != null) {
this.textValue = chooseText //获取到选中的值
this.dialogController.open()
}
}
this.animatorResult.play();
}
完成
选中的内容,大家可以定义一个弹框弹出即可
总结
是不是简简单单,老板叫我干啥我干啥,这点需求不在话下,可以找老板涨工资啦!!!
冲冲冲