快过年了。各公司单位都要开年会什么的。
这时候不免都要抽个奖。
简单用canvas做了一个抽奖转盘
主要看注释吧

在线预览:https://codepen.io/andy-js/pen/mdyqwKE
右键打开新窗口预览效果更好哦!

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>andy-js:抽奖大转盘</title>
<style>
*{margin:0;padding:0;}
#box{width:500px;height:500px;margin:0 auto; position: relative;}
#btn{height:40px;line-height: 40px;color:#fff;text-align: center;position:absolute;left:0;top:0;width:300px;}
#btn input{width:100px;height:100px;}
#box span{width:4px;height:160px;background: #0f0;position: absolute;left:50%;top:50%;margin-left:-2px;margin-top:-160px;}
canvas{
    transform-origin:250px 250px;
}
</style>
</head>

<body>
<div id="box">
    <canvas id="c1" width="500" height="500"></canvas>
    <span></span>
</div>
<div id="btn">
    <input type="button" value="点击开始" >
</div>
<script>

var data=[   //投奖数据
    'iphone11',
    'iphone12',
    'iphone13',
    'iphone14',
    'iphone15',
    'iphone16'
];

var oBtn=document.getElementById('btn').children[0];
var oBox=document.getElementById('box');
var oC1=document.getElementById('c1');
var ctx = oC1.getContext("2d");
var radius=oBox.offsetWidth/2;


var angle=0,  //旋转的角度 
    speed,// 旋转速度
    cut, //是否需要减速了
    timer1,timer2;  
render();  //默认状态

oBtn.onclick=function(){
    clearInterval(timer1);
    clearInterval(timer2);
    speed=10;
    cut=false;
    timer1=setInterval(function(){
        var now=Date.now();
        if(cut&&now-cut>500){  //每500毫秒降一档速度
            speed--;
            cut=now;
        };
        angle+=speed;
        oC1.style.transform='rotate('+(angle%360)+'deg)';

        if(speed==0)clearInterval(timer1);
    },60);
    timer2=setTimeout(function(){  //让子弹飞一会
        cut=Date.now();
    },Math.random()*(6000-3000+1)+3000);    //随机时间  3-6秒内
};

//画线和文字  
function render(){
    ctx.clearRect(0, 0, 2 * radius, 2 * radius);   //每次都清空画布 重新画

    //画红色底圆
    ctx.fillStyle="#FF0000";
    ctx.beginPath();  //起始一条路径
    ctx.arc(radius,radius,radius,0,Math.PI*2,true);//创建弧
    ctx.closePath();
    ctx.fill();//填充当前绘图(路径)

    ctx.translate(radius, radius);  //重新映射画布上的 (0,0) 位置  映射到画布正中间 
    ctx.lineWidth = 1;    //线的宽度
    ctx.strokeStyle = "#fff";  //用于线条颜色
    ctx.fillStyle='blue';  //用于文字颜色
    ctx.font="20px Georgia";
    ctx.textAlign='center';  //根据Y轴居中
    var i=0,l=data.length;
    ctx.rotate( Math.PI / l );    //先旋转一次,可以让指针在文字中间
    for (i; i < l; i++) {  
        //线条 
        ctx.beginPath();   //起始一条路径
        ctx.moveTo(0, 0);  //画直线的起点,从中心开始
        ctx.lineTo(0, -radius);  //然后一直画到半径最边上
        ctx.stroke();  //绘制已定义的路径
        ctx.closePath();  //关闭路径  
        ctx.rotate(  Math.PI / l  );   //旋转当前画布  Math.PI=180度=30分钟=半圆   所以这里旋转一次是将半圆分成了六份  正好可以写文字,然后再旋转

        //文字
        ctx.fillText(data[i],0,-radius+60);
        ctx.rotate(  Math.PI / l  );
    };
} ;





</script>
</body>
</html>

当然,我这里都是奖品随机的,机率都一样
在真正的投奖中,肯定需要设置容易度。
比如最贵的肯定最难抽,并且如果只有一个的大奖,抽到了就应该不会再转到。
需要用到的朋友自己思考下吧。


andy
6 声望3 粉丝

贪财好色!经不住诱惑!