最近公司有一个对外活动,需要用到抽奖模块。本来是想用易企秀的大转盘抽奖模块,但是产品上还有一个需求是,通过语音控制开始抽奖(语音部分另说,通过安卓APP做的,进行APP与H5通信实现语音控制),抱歉的是,易企业秀不支持获取其页面内的元素来控制开始抽奖(跨域了)。同样的,抽奖的概率、奖品等等需要通过配置来控制。因此手写一个抽奖的效果,而不是UED出固定的设计图前端做一个转动的效果。
1、设计图
2、任务分析
1.绘制一个圆,并实现最外面的border
2.绘制第二层border,并实现内部有原点的效果
3.绘制分隔区域,沿着圆形径向分割成若干份,并有明显的分割线
4.每个区域布局,实现将奖项图片与文本沿着绘制好的分隔区域放置好
5.点击抽奖按钮,整体实现旋转,并按照概率落在某一个奖项处
2.1、绘制一个圆,并实现最外层border
这个使用border属性即可
border: 20px #f6f7d0 solid;
border-radius: 50%;
2.2、绘制第二层圆,有一定的宽度,并有10个小圆点包含其中
这个实现思路是运用伪类、box-shadow属性组合来实现:
box-shadow中每个值的计算方法可以对应到笛卡尔坐标系上,进行计算。(box-shadow的x、y偏移量以右下为正值,与传统的笛卡尔坐标系略有不同)
文中Demo将一个圆分成8份,(用于计算的长宽通过)每个点的坐标是:80(200/2-40/2)对应的正弦、余弦值,角度为45度(360/8),例如:80sin(45)=56.7、80cos(45)=56.7等等,详情如下:
.main-circle::before{
box-shadow:
0 -80px 0 0 red,
57px -57px 0 0 red,
80px 0 0 0 red,
57px 57px 0 0 red,
0 80px 0 0 red,
-57px 57px 0 0 red,
-80px 0 0 0 red,
-57px -57px 0 0 red
}
2.3、将一个圆分成若干等份,并中间有一条分割线
分析之前,想用的是不同的色块填充相邻区块,这样天然就有分割线效果,但是这和设计稿不符,设计师要求的是园内整体颜色一样,但是可以作为一个参考思路: 不符要求的效果如下:
那该怎么通过css实现呢?
这里用到一个css函数,conic-gradient,详细使用方法见MDN:developer.mozilla.org/zh-CN/docs/…
具体实现Demo为:
2.4、每个区域布局,实现将奖项图片与文本沿着绘制好的分隔区域放置好
这个效果通过定位、旋转组合实现
2.5、点击抽奖按钮,整体实现旋转
这个效果通过动画实现
2.6、概率部分
模拟概率,如下例子表示的概率是:
一等奖:5%
二等奖:10%
三等奖:30%
幸运奖:40%
没中奖:15%
const lotteryProbability = () => {
// 生成随机数,表示转盘停在的位置
const random = Math.random() * 100;
// 根据概率确定中奖结果
if (random < 5) {
return state.prizeList[0];
} else if (random < 15) {
return state.prizeList[1];
} else if (random < 45) {
return state.prizeList[2];
} else if(random < 85){
return state.prizeList[3];
}else{
return state.prizeList[4];
}
}
3、整体效果代码
4、总结
如上效果用到了css3样式中的box-shadow、conic-gradient,灵活运用