大转盘啊,大转盘。看了好多代码,很多都是通过canvas实现的,也有别的是通过计时器实现的,但是无非js代码多的一批,还看不懂。
没用canvas!没用canvas!没用canvas!你没听错,这里只要你css+html学的好,简单的 animation 动画,教你做大转盘!
下面我将分几个步骤,告诉大家如何实现的,想直接看代码的,可以直接看最下面的代码
实现步骤:
1.文字,img,抽奖按钮的布局
实现下图的样子,相比大家应该都知道怎么搞,抽奖按钮这里就不做过多介绍了,只要通过position定位居中下就可以了
然后就通过改变每个标签的旋转角度和位移距离就实现了文字的布局
:style="`transform: rotate(${-index*360/list.length}deg) translateY(-7.5rem);`"
2.转盘的扇形背景
相信很多人都会在这里遇到坑,进而选择了canvas去实现,当然我们这里不用canvas!!
这里主要运用的是css的 transform:skew()倾斜属性。
美丽的扇形看下图~~
相比看了上面的图片,你应该会有一个大致的想法了 这里我简单的先用3个奖品来讲解,免得太多,不容易理解
看完上图的介绍后,你会发现最终的扇形,并没有很好的和文字对应,这里我直接通过控制整个扇形的旋转,来达到对应效果,于是在最外层进行了控制,因为这里的
list奖品个数为3,所以偏移的角度就是-30deg
:style="` transform: rotate(${-90+180/list.length}deg)`"
3.轮盘的转动
通过每个class类名,对应不同的animation动画来实现,这样通过每次点击抽奖时,更换不同的class类名就可以实现动画的转动
例如:
| 奖品 | 默认角度 | class类名 | animation动画(奖品数为4个时 ) |
|---|---|---|---|
| 特等奖 | 360deg/奖品个数*0 | .wr0 | play0(开始时:0deg 结束时:1800deg+0deg) |
| 一等奖 | 360deg/奖品个数*1 | .wr1 | play1(开始时:0deg 结束时:1800deg+90deg) |
| 二等奖 | 360deg/奖品个数*2 | .wr2 | play2(开始时:0deg 结束时:1800deg+180deg) |
| 三等奖 | 360deg/奖品个数*3 | .wr3 | play3(开始时:0deg 结束时:1800deg+270deg) |
遇到的问题和解决方案:
1.轮盘转动时,若下次中奖和本次中奖一致,class类名不改变,动画不执行问题;
this.panziElement = document.querySelector('.panzi')
this.panziElement.classList.remove(this.animationClass)
setTimeout(() => {
/* 此处是为了解决当下次抽中的奖励与这次相同,动画不重新执行的 */
/* 添加一个定时器,是为了解决动画属性的替换效果,实现动画的重新执行 */
this.panziElement.classList.add(this.animationClass)
}, 0)
2.在上面描述的 轮盘的转动中,可以看出要事先定义好animation动画,动画最后得到的旋转角度根据奖品个数而定;
mounted() {
//通过获取奖品个数,来改变css样式中每个奖品动画的旋转角度
// var(--nums) 实现css动画根据奖品个数,动态改变
let root = document.querySelector(':root')
root.style.setProperty('--nums', this.list.length)
},
@keyframes play0 {
to {
transform: rotate(calc(5 * 360deg + 360deg / var(--nums) * 0));
}
}
使用参数:
winner: 2, //指定获奖下标 specified为true时生效
specified: false, //是否指定获奖结果,false时为随机
loading: false, //抽奖执行状态,防止用户多次点击
panziElement: null,
list: [ ] //奖品列表
$zp_size: 23rem; //转盘尺寸
$btn_size: 7rem; //抽奖按钮尺寸
$time: 3s; //转动多少秒后停下的时间
大家看到代码的时候,会发现我已经预先写好了 8个奖品时的相关class类名,如果你的奖品个数在 8 个以下,你只需要修改list奖品列表里面的个数就可以了,除非你的奖品在 8 个以上,那么就需要你多加点class类名了。
你肯定会问:'为什么多了要加,少了就不用删呢?'
比如你的奖品个数是3个,那么肯定不存在 .wr4 类名,也就不会有 play4的动画 ,而且动画的旋转角度已经是根据 遇到的问题和解决方案2: var(--nums) 而改变了,所以你就不用管了~~