如图,抽奖转盘,可以拆分为几部分:
1.底部大圆;
2.中间小圆;
3.扇形区;
4.扇形内部奖品区;
5.抽奖按钮;
6.点击抽奖按钮时旋转动效及逻辑;
这其中,扇形区,以及扇形区内奖品的布局最为关键和麻烦,这个问题解决,剩下的问题,那都不是事儿!
那如何用Css优雅的实现呢?——最关键的就是扇形区的绘制!
这里用到css的两个关键属性:rotate skewY;旋转和倾斜;
首先我们先来绘制一个扇形:
步骤:
1.先画一个圆形:
css代码:
.container { width: 300px; height: 300px; background-color: red; border-radius: 50%; display: flex; justify-content: center; align-items: center; position: relative; }
复制
2.在圆形上,再画一个同大小的正方形,并将正方形左下角与圆心对齐,为了区分不同的区域,加上一个border:
css代码:
.prize-container { width: 280px; height: 280px; background-color: bisque; position: absolute; left: 50%; top: -50%; background-color: antiquewhite; border: 1px solid red; }
复制
3.关键点,如何通过skewY,将这个正方形倾斜:skew属性有skew,skewX,skewY,这里我们选择使用skewY,也就是顺着Y轴倾斜。通过上图,我们很容易想到,要想得到一个扇形,我们可以设置overflow: hidden,直接就能得到一个90°角的扇形:
但假如有6个奖品,那么每个奖品的扇形区就是360/6=60°。那如何将90°变为60°呢?上面我们说了,可以使用倾斜属性,即将正方形以左下角(圆心)为中心,向上提拉倾斜到夹角变为60°为止,上代码:
transform-origin: 0% 100%; transform: skewY(-30deg);
复制
首先我们要明白坐标系,以正方形为例,左上角为坐标原点(0,0),x轴往右为正,往左为负,y轴往下为正,往上为负,所以左下角坐标就是(0% ,100%),transform-origin: 0% 100%即以左下角为中心倾斜;y轴向上为负,所以向上倾斜30°即transform: skewY(-30deg)。
4.总共6个奖品,那么就需要6个扇形区,上面我们已经得到了一个扇形模板,剩下的我们只需要使用rotate属性旋转对应角度即可,第一个不需要旋转,旋转角度为0,第二个需要旋转60°,第三个120°…最后得到的效果如图:
父布局加上overflow: hidden属性:
大功告成!
剩下的就是奖品内容区,这个比扇形区绘制更简单一点,只需要使用rotate属性即可:
.prize { width: 140px; height: 140px; position: absolute; left: 50%; top: 0; transform-origin: 0% 100%; } .prize-child { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; transform: rotate(30deg) translateX(-15%) translateY(10%); }
复制
<div class="prize"> <div class="prize-child"> <div>奖品</div> <p>1等奖</p> </div> </div>
复制
我们设置一个长宽为圆形半径长度的正方形,在里面布局奖品内容,然后旋转30°即可,为什么要旋转30?因为内容是在扇形区的轴心,扇形区是60°,那么内容只需要旋转30°即可:
而translateX(-15%) translateY(10%)则是根据你的具体奖品内容布局,去调节显示位置的,这个不是固定的!
那6个奖品,就可以通过prize 旋转对应角度即可,原理同扇形区:
加上一个抽奖按钮,最终效果:
当然,可能实际情况并非正好固定6个奖品,也可能是8个,或其它数量,这个就需要你根据奖品个数,动态计算应该旋转的角度,旋转角度一般为:
扇形旋转角度:index360/count,
倾斜角度:index360/count-90
奖品旋转角度:index*360/count+360/count/2
index即奖品list的下标,count即奖品数量!
完整代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>抽奖</title> </head> <style> .body { width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; } .container { width: 300px; height: 300px; background-color: red; border-radius: 50%; display: flex; justify-content: center; align-items: center; position: relative; } .turntable { width: 280px; height: 280px; border-radius: 50%; position: absolute; overflow: hidden; } /*扇形区*/ .prize-container { width: 280px; height: 280px; background-color: bisque; position: absolute; left: 50%; top: -50%; /*600-280/2,将prize正方形左下角点对准圆心*/ border: 1px solid red; /*以正方形左下角为中心旋转,0% 100%即左下角的坐标*/ transform-origin: 0% 100%; } .prize-container:nth-child(1) { transform: rotate(0deg) skewY(-30deg); } .prize-container:nth-child(2) { transform: rotate(60deg) skewY(-30deg); } .prize-container:nth-child(3) { transform: rotate(120deg) skewY(-30deg); } .prize-container:nth-child(4) { transform: rotate(180deg) skewY(-30deg); } .prize-container:nth-child(5) { transform: rotate(240deg) skewY(-30deg); } .prize-container:nth-child(6) { transform: rotate(300deg) skewY(-30deg); } /* 奖品区 */ .prize { width: 140px; height: 140px; position: absolute; left: 50%; top: 0; transform-origin: 0% 100%; } /* 奖品内容 */ .prize-child { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; transform: rotate(30deg) translateX(-15%) translateY(10%); } .prize:nth-child(1) { transform: rotate(0deg); } .prize:nth-child(2) { transform: rotate(60deg); } .prize:nth-child(3) { transform: rotate(120deg); } .prize:nth-child(4) { transform: rotate(180deg); } .prize:nth-child(5) { transform: rotate(240deg); } .prize:nth-child(6) { transform: rotate(300deg); } .draw-btn { width: 80px; height: 80px; border-radius: 50%; background-color: red; color: white; font-size: 30px; line-height: 80px; text-align: center; position: absolute; } </style> <script> function drawPrize() { alert("抽奖"); } </script> <body class="body"> <div class="container"> <div class="turntable"> <div class="prize-container"></div> <div class="prize-container"></div> <div class="prize-container"></div> <div class="prize-container"></div> <div class="prize-container"></div> <div class="prize-container"></div> </div> <div class="turntable"> <div class="prize"> <div class="prize-child"> <div>奖品</div> <p>1等奖</p> </div> </div> <div class="prize"> <div class="prize-child"> <div>奖品</div> <p>2等奖</p> </div> </div> <div class="prize"> <div class="prize-child"> <div>奖品</div> <p>3等奖</p> </div> </div> <div class="prize"> <div class="prize-child"> <div>奖品</div> <p>4等奖</p> </div> </div> <div class="prize"> <div class="prize-child"> <div>奖品</div> <p>5等奖</p> </div> </div> <div class="prize"> <div class="prize-child"> <div>奖品</div> <p>6等奖</p> </div> </div> </div> <div class="draw-btn" onclick="drawPrize()">抽</div> </div> </body> </html>
复制