引言:幸运大转盘在很多网站上、APP都有出现,之前的话一直也没有去琢磨,自从把canvas学了一遍后,什么都想自己做一个,这不就写了个幸运大转盘玩玩,欢迎大家来指导交流!
页面效果:
实现思路
- 绘制外围的大转盘,就是绘制两个圆然后填充好颜色,第2个圆稍小些;
- 绘制6个扇形,因一个圆360度分成6份,故每份60度,根据度数计算出开始角度、结束角度,即可绘制出6个连续放置的扇形,分别配置不同的颜色;
- 在每个扇形的位置分别绘制奖项卡,也是根据角度来计算,然后把对应的图片绘上去;
- 在大转盘中心绘制指针图片,同时绘制一个跟图片大小接近的圆(白色填充),鼠标的移入和点击事件就靠这个圆来控制;
- 在大转盘外围绘制修饰小灯(即根据角度来绘制多个小圆);
- 点击转盘中心的指针,转动转盘(改变各个元素的绘制开始角度、结束角度即可);
- 停止转动后,判断指针在谁的角度范围内,判断中奖情况。
开始绘制
注意:圆绘制和图片绘制 的构造函数,放到 util.js 中了,这里就不放代码了,之前很多实例都有这些代码,下载源码也可以看到。
绘制外围的大转盘
有两个圆组成,最外面的大圆和半径小20的圆(都是填充的)
-
//绘制外围的轮盘
-
zhuanPan.prototype.drawWheel=
function(){
-
var x=y=
0,cilcle,color;
-
x=
this.w/
2;y=
this.h/
2,color=
'#FFBB00';
-
//最外围的大圆
-
cilcle =
new _.Circle({
-
x:x,
//圆心X坐标
-
y:y,
//圆心X坐标
-
r:y,
//半径
-
startAngle:
0,
//开始角度
-
endAngle:
2*
Math.PI,
//结束角度
-
fill:
true,
-
fillStyle:color
-
});
-
this.renderArr.push(cilcle);
-
//半径稍小20的圆
-
color=
'#FF8300';
-
cilcle =
new _.Circle({
-
x:x,
//圆心X坐标
-
y:y,
//圆心X坐标
-
r:y
-20,
//半径
-
startAngle:
0,
//开始角度
-
endAngle:
2*
Math.PI,
//结束角度
-
fill:
true,
-
fillStyle:color
-
});
-
this.renderArr.push(cilcle);
-
}
此时绘制的效果:
绘制选项卡
由一个圆360度分成6份,每份60度,然后计算开始角度、结束角度绘制扇形,并且2种颜色填充,来回切换这2种颜色
-
zhuanPan.prototype.drawCard=
function(){
-
var x=y=
0,cilcle,color,level,startAngle,endAngle,angle;
-
x=
this.w/
2;y=
this.h/
2,tx=ty=
0;
-
for(
var i=
0;i<
6;i++){
-
startAngle = i*
2*
Math.PI/
6,
-
endAngle = (i+
1)*
2*
Math.PI/
6,
-
color=i%
2==
0?
'#FFEAB1':
'#FFFFFF';
-
cilcle =
new _.Circle({
-
x:x,
//圆心X坐标
-
y:y,
//圆心X坐标
-
r:y
-26,
//半径
-
startAngle:startAngle,
//开始角度
-
endAngle:endAngle,
//结束角度
-
fill:
true,
-
fillStyle:color
-
});
-
cilcle.level=i;
-
this.renderArr.push(cilcle);
-
this.cardArr.push(cilcle);
-
}
-
-
}
此时绘制效果:
绘制选项卡对应的图片
每次旋转60度放置图片、跟绘制奖项卡差不多,需要注意的时候绘制图片的时候,x、y均要做适量的偏移(代码中的 disX=60,disY=20)
-
//绘制选项图片
-
zhuanPan.prototype.drawCardImage=function(){
-
var angle,image,img,x=
this.w
/2;y=this.h/
2,sx=
0,sy=
0,sWidth=
64,sHeight=
64,dx=x,dy=y,dWidth=
64,dHeight=
64,disX=
60,disY=
20;
-
var arr=[
4,
10,
5,
10,
6,
10];
//图片位置数组(这是根据加载图片存储的下标来写的)
-
for(var i=
0;i<
6;i++){
-
angle = i*
-60;
-
image =
this.imgObj[arr[i]];
-
img =
new _.ImageDraw({
image:image,
sx:sx,
sy:sy,
sWidth:sWidth,
sHeight:sHeight,
dx:dx,
dy:dy ,
dWidth:dWidth,
dHeight:dHeight,
angle:angle,
disX:disX,
disY:disY});
-
this.renderArr.push(img);
-
this.cardImageArr.push(img);
-
}
-
}
绘制指针
1.绘制一个小圆,跟图片大小差不多,用来判断鼠标移入指针事件和鼠标点击指针事件。
2.绘制图片时,x、y的渲染位置要做一些偏移,不在圆心位置,因为图片的绘制和圆的绘制有一些差别。
-
//绘制指针
-
zhuanPan.prototype.drawPointer=function(){
-
var x=
this.w/
2;y=
this.h/
2+
7;
-
var pointerCilcle = new _.Circle({
-
x:x,
//圆心X坐标
-
y:y,
//圆心X坐标
-
r:
24,
//半径
-
startAngle:
0,
//开始角度
-
endAngle:
2*Math.PI,
//结束角度
-
fill:
true,
-
fillStyle:
"red"
-
});
-
this.renderArr.push(pointerCilcle);
-
this.pointerObj=pointerCilcle;
-
-
var image =
this.imgObj[
11];
-
x=y=
0;
-
var img,sWidth=
64,sHeight=
64,dx=
this.w/
2-
32,dy=
this.h/
2-
32,dWidth=
64,dHeight=
64;
-
img = new _.ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight});
-
this.renderArr.push(img);
-
}
绘制外围修饰的小圆
-
//装饰灯
-
zhuanPan.prototype.drawLight=
function(){
-
var x=y=r=
0,cilcle,color,level,startAngle,endAngle,angle;
-
x=
this.w/
2;y=
this.h/
2,tx=ty=
0;
-
for(
var i=
0;i<
12;i++){
-
color=i%
2==
0?
'#FDFEC1':
'#FEFCFB';
-
r=i%
2==
0?
4:
6;
-
cilcle =
new _.Circle({
-
x:x,
//圆心X坐标
-
y:y,
//圆心X坐标
-
r:r,
//半径
-
disX:
170,
//x方向偏移
-
startAngle:
0,
//开始角度
-
endAngle:
2*
Math.PI,
//结束角度
-
fill:
true,
-
fillStyle:color,
-
angle:i*
-30
-
});
-
cilcle.level=i;
-
this.renderArr.push(cilcle);
-
this.lightArr.push(cilcle);
-
}
-
}
页面的绘制已经完成了,看起来还不错呢。
接下来加入鼠标事件
鼠标移动事件
判断是鼠标的位置,是否处于指针位置的小圆范围内,如果在鼠标就变成手的形状,否则鼠标就普通的形状。
-
//鼠标移动事件
-
zhuanPan.prototype.mouseMove=function(e){
-
var pos = _.getOffset(e);
//获取鼠标位置
-
var isCatch =
this.pointerObj.isPoint(pos);
//鼠标捕捉
-
if(isCatch){
-
this.el.style.cursor =
'pointer';
//改为手状形态
-
}
else{
-
this.el.style.cursor =
'';
-
}
-
}
鼠标点击事件
1.开启定时任务,每次以10度的角度来旋转;
2.随机一个范围0-360的角度,默认旋转2圈,2圈之后再旋转刚才随机出来的角度,待随机的角度旋转到位后,停止旋转,然后判断中奖情况;
3.判断指针的角度在哪个奖项卡的开始和结束角度内,则确定中奖情况。
-
//转动
-
zhuanPan.prototype.rotate=
function(){
-
var that=
this;
-
doUpdate.call(that);
-
function doUpdate(){
-
var flag=
false;
-
_.each(that.cardArr,
function(item){
-
//角度旋转
-
item.angle -=
10;
-
-
if(that.catchStartFlag){
-
//因为到-360度是时候就会重置为0
-
if(item.level==
0 && item.angle<=-that.endRandomAngle){
-
that.catchStartFlag=
false;
-
clearInterval(that.timmer);
-
that.timmer=
null;
-
that.timeCount=
0;
-
that.cardCatch();
-
}
-
}
-
-
//达到最大角度则重置角度
-
if(item.angle<=
-360){
-
item.angle=
360+item.angle;
-
if(!flag){
-
that.timeCount++;
-
flag=
true;
-
}
-
}
-
});
-
_.each(that.cardImageArr,
function(item){
-
//角度旋转
-
item.angle -=
10;
-
//达到最大角度则重置角度
-
if(item.angle<=
-360){
-
item.angle=
360+item.angle;
-
}
-
});
-
-
-
_.each(
this.lightArr,
function(item,i){
-
//角度旋转
-
item.angle -=
10;
-
//达到最大角度则重置角度
-
if(item.angle<=
-360){
-
item.angle=
360+item.angle;
-
}
-
})
-
this.render();
-
}
-
if(that.timeCount==
2){
//进入捕获阶段
-
that.catchStartFlag=
true;
-
}
-
}
-
//中奖捕获
-
zhuanPan.prototype.cardCatch=
function(){
-
var catchAngle=
270-
this.endRandomAngle;
//中奖捕获角度
-
catchAngle = catchAngle<
0?catchAngle+
360:catchAngle;
-
var max ,min,levelArr=
this.levelArr;
-
var that=
this;
-
_.each(
this.cardArr,
function(item){
-
min = item.startAngle*
180/
Math.PI ;
-
max = item.endAngle*
180/
Math.PI ;
-
-
if(catchAngle>min && catchAngle<max){
-
var result = levelArr[item.level];
-
console.log(
"result=="+result);
-
setTimeout(
function(){
-
alert(result)
-
},
100)
-
}
-
})
-
}
代码就完成了
源码下载
方式1:少量积分,下载代码
方式2:关注下方公众号,回复 125 下载代码
★ 更多源码
♥ 老父亲给女儿做的下雪特效,满足女儿看雪的愿望(附源码)♥
♥ 香港黄金配角吴孟达去世,80后程序员以轮播图来悼念达叔,达叔一路走好!(附源码)♥
♥ 原生js写的左侧飞入拼图特效,你是喜欢美女单飞还是双飞(附源码)♥
♥ 用js写的旋转木马,在新年献给各位刚登基的皇帝,让你的后宫转起来!程序员就是可以为所欲为!(附源码)♥
♥ 用js写的轮播图,八位女明星,你翻谁的牌,程序员就是可以为所欲为!(附源码)♥
♥ 原生js实现美女拼图,把美女老婆抱回家,5个美女够不够!程序员就是可以为所欲为!(附源码)♥
♥ 用js仿探探拖拽卡片的效果、飞卡片的效果,感觉挺酷,最后有美女看哦!(附源码)♥
♥ 老婆说程序员不懂浪漫,程序员默默拿起了键盘,这就亲手带你去看流星雨,女人真的会影响拔刀的速度!(附源码)♥
♥ 学生成绩管理系统(jsp+jquery+java+mysql+tomcat)有源码,你的毕设我的心(附源码)♥
转载:https://blog.csdn.net/dkm123456/article/details/115457093