根据CSS新特性写一个抽奖转盘的效果

2,202 阅读3分钟

    最近公司有一个对外活动,需要用到抽奖模块。本来是想用易企秀的大转盘抽奖模块,但是产品上还有一个需求是,通过语音控制开始抽奖(语音部分另说,通过安卓APP做的,进行APP与H5通信实现语音控制),抱歉的是,易企业秀不支持获取其页面内的元素来控制开始抽奖(跨域了)。同样的,抽奖的概率、奖品等等需要通过配置来控制。因此手写一个抽奖的效果,而不是UED出固定的设计图前端做一个转动的效果。

1、设计图

image.png

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  
}

image.png

当然这个样式也可以写在js里面按照奖品的份数进行css计算

2.3、将一个圆分成若干等份,并中间有一条分割线

分析之前,想用的是不同的色块填充相邻区块,这样天然就有分割线效果,但是这和设计稿不符,设计师要求的是园内整体颜色一样,但是可以作为一个参考思路: 不符要求的效果如下:

image.png

那该怎么通过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、整体效果代码

lucy.png lottery-btn.png first.png second.png thanks.png third.png

4、总结

如上效果用到了css3样式中的box-shadow、conic-gradient,灵活运用