canvas draw Big Wheel

Renderings
Here Insert Picture Description
implementation code and Demo

<!DOCTYPE html>
<html>
<head>
	<meta name="keywords" content="风舞红枫,前端技术,canvas"/>
	<meta name="description" content="风舞红枫,前端技术,canvas,vue,react,node,个人博客"/>
	<meta charset="utf-8">
	<link rel="icon" href="../image/icon2.ico">
	<title>大转盘</title>
	<style type="text/css">
		*{margin:0;padding:0;}
		canvas{position:absolute;top:0;bottom:0;left:0;right:0;margin:auto;}
		img{display:none;}
	</style>
</head>
<body>
	<canvas></canvas>
	<img src="1.png" id="one">
	<img src="4.png" id="two">
</body>
<script type="text/javascript">
window.onload = function(){
	class FwhfTurntable{
		constructor(){
			this.canvas = document.getElementsByTagName('canvas')[0];
			this.context = this.canvas.getContext('2d');
			//小灯的个数
			this.lightNum = 12;
			//讲评列表
			this.prizeList = [
				{text:'特等奖',img:document.getElementById('one')},
				{text:'一等奖',img:document.getElementById('one')},
				{text:'二等奖',img:document.getElementById('one')},
				{text:'三等奖',img:document.getElementById('two')},
				{text:'奖励奖',img:document.getElementById('two')},
				// {text:'test1',img:document.getElementById('two')},
				// {text:'test2',img:document.getElementById('two')},
				{text:'未中奖',img:document.getElementById('two')}
			];
			this.timer = null;
			this.rotateStart = 0;
			this.rotateEnd = 0;
			this.prizeListStore = [];
		}
		innt(){
			this.canvas.width = 400;
			this.canvas.height = 400;
			if(this.rotateStart == this.rotateEnd){
				for(var i = 0 ; i < this.prizeList.length ; i++){
					this.prizeList[i].startAngle = (i*360/this.prizeList.length+90)%360;
				}
				this.bgLight();
				this.prize();
				this.pointer();
				this.canvas.onclick = function(e){
					if(e.offsetX > 180 && e.offsetX < 220 && e.offsetY > 180 && e.offsetY < 220){
						//具体概率根据需求修改,此处不作处理,随机任意值
						this.rotateEnd += this.rand(1000,2000);
						this.timer = setInterval(()=>{
							this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
							this.bgLight();
							this.prize();
							this.pointer();
							if(this.rotateStart >= this.rotateEnd){
								clearInterval(this.timer);
								this.timer = null;
								this.rotateStart = this.rotateEnd;
								for(var i = 0 ; i < this.prizeList.length ; i++){
									if((this.rotateStart+this.prizeList[i].startAngle)%360 > 360-360/this.prizeList.length){
										setTimeout(()=>{
											alert(this.prizeList[i].text);
										},500)
										break;
									}
								}
							}
						},30)
					}
				}.bind(this);
			}
		}
		//周边背景灯
		bgLight(){
			this.context.beginPath();
		    this.context.fillStyle="red";
		    this.context.arc(200,200,200,0,2*Math.PI);
		    this.context.fill();
		    this.context.closePath();

		    this.context.beginPath();
		    this.context.fillStyle="#f069a8";
		    this.context.arc(200,200,180,0,2*Math.PI);
		    this.context.fill();
		    this.context.closePath();

		    for(var i = 0 ; i < this.lightNum ; i++){
		    	this.context.beginPath();
			    this.context.fillStyle= this.rand(0,9) == 0 ? "#f5c058" : "white";
			    this.context.arc(200+190*Math.cos(360/this.lightNum*i*Math.PI/180),200+190*Math.sin(360/this.lightNum*i*Math.PI/180),6,0,2*Math.PI);
			    this.context.fill();
			    this.context.closePath();
		    }
		}
		//奖品扇形
		prize(){
			if(this.rotateStart < this.rotateEnd){
				this.rotateStart += Math.ceil((this.rotateEnd-this.rotateStart)/20);
			}
			this.context.save();
			this.context.translate(200,200);
			this.context.rotate(this.rotateStart*Math.PI/180);
			this.context.translate(-200,-200);
			for(var i = 0 ; i < this.prizeList.length ; i++){
				this.context.save();
				this.context.translate(200,200);
				this.context.rotate(360/this.prizeList.length*i*Math.PI/180);
				this.context.translate(-200,-200);
				this.context.beginPath();
				if(i%2 == 0){
					this.context.fillStyle="#ffe8b5";
				}else{
					this.context.fillStyle="#ffb933";
				}
				this.context.moveTo(200,200);
			    this.context.arc(200,200,170,0,2/this.prizeList.length*Math.PI);
			    this.context.fill();
			    this.context.closePath();

			    this.context.save();
			    this.context.translate(290,260);
			    this.context.rotate((130-this.prizeList.length*2)*Math.PI/180);
			    this.context.translate(-290,-260);
			    this.context.beginPath();
			    this.context.fillStyle="#5c1e08";
			    this.context.font="18px Georgia";
			    this.context.fillText(this.prizeList[i].text,280-this.prizeList.length*5,230);
			    this.context.fill();

			    this.context.drawImage(this.prizeList[i].img,280-this.prizeList.length*5,240)
			    this.context.closePath();
			    this.context.restore();

			    this.context.restore();
		   	}
		   	this.context.restore();
		}
		//指针
		pointer(){
			this.context.beginPath();
		    this.context.fillStyle="red";
		    this.context.arc(200,200,30,0,2*Math.PI);
		    this.context.fill();

		    this.context.moveTo(185,200);
		    this.context.lineTo(215,200);
		    this.context.lineTo(200,120);
		    this.context.fill();
		    this.context.closePath();

		    this.context.beginPath();
		    this.context.fillStyle="#000";
		    this.context.font="bold 16px Georgia";
		    this.context.fillText("抽奖",186,206);
		    this.context.closePath();
		}
		rand(n,m){
			var c = m - n + 1;
			return Math.floor(Math.random() * c + n);
		}
	}
	new FwhfTurntable().innt();
}
</script>
</html>
Published 14 original articles · won praise 14 · views 935

Guess you like

Origin blog.csdn.net/qq_42231248/article/details/90481391