快过年了。各公司单位都要开年会什么的。
这时候不免都要抽个奖。
简单用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>
当然,我这里都是奖品随机的,机率都一样
在真正的投奖中,肯定需要设置容易度。
比如最贵的肯定最难抽,并且如果只有一个的大奖,抽到了就应该不会再转到。
需要用到的朋友自己思考下吧。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。