飞道的博客

基于JavaScript的幸运大转盘

317人阅读  评论(0)

引言:幸运大转盘在很多网站上、APP都有出现,之前的话一直也没有去琢磨,自从把canvas学了一遍后,什么都想自己做一个,这不就写了个幸运大转盘玩玩,欢迎大家来指导交流!

页面效果:

实现思路

  1. 绘制外围的大转盘,就是绘制两个圆然后填充好颜色,第2个圆稍小些;
  2. 绘制6个扇形,因一个圆360度分成6份,故每份60度,根据度数计算出开始角度、结束角度,即可绘制出6个连续放置的扇形,分别配置不同的颜色;
  3. 在每个扇形的位置分别绘制奖项卡,也是根据角度来计算,然后把对应的图片绘上去;
  4. 在大转盘中心绘制指针图片,同时绘制一个跟图片大小接近的圆(白色填充),鼠标的移入和点击事件就靠这个圆来控制;
  5. 在大转盘外围绘制修饰小灯(即根据角度来绘制多个小圆);
  6. 点击转盘中心的指针,转动转盘(改变各个元素的绘制开始角度、结束角度即可);
  7. 停止转动后,判断指针在谁的角度范围内,判断中奖情况。

开始绘制

注意:圆绘制和图片绘制 的构造函数,放到 util.js 中了,这里就不放代码了,之前很多实例都有这些代码,下载源码也可以看到。

绘制外围的大转盘

有两个圆组成,最外面的大圆和半径小20的圆(都是填充的)


  
  1. //绘制外围的轮盘
  2. zhuanPan.prototype.drawWheel= function(){
  3. var x=y= 0,cilcle,color;
  4. x= this.w/ 2;y= this.h/ 2,color= '#FFBB00';
  5. //最外围的大圆
  6. cilcle = new _.Circle({
  7. x:x, //圆心X坐标
  8. y:y, //圆心X坐标
  9. r:y, //半径
  10. startAngle: 0, //开始角度
  11. endAngle: 2* Math.PI, //结束角度
  12. fill: true,
  13. fillStyle:color
  14. });
  15. this.renderArr.push(cilcle);
  16. //半径稍小20的圆
  17. color= '#FF8300';
  18. cilcle = new _.Circle({
  19. x:x, //圆心X坐标
  20. y:y, //圆心X坐标
  21. r:y -20, //半径
  22. startAngle: 0, //开始角度
  23. endAngle: 2* Math.PI, //结束角度
  24. fill: true,
  25. fillStyle:color
  26. });
  27. this.renderArr.push(cilcle);
  28. }

此时绘制的效果:

绘制选项卡

由一个圆360度分成6份,每份60度,然后计算开始角度、结束角度绘制扇形,并且2种颜色填充,来回切换这2种颜色


  
  1. zhuanPan.prototype.drawCard= function(){
  2. var x=y= 0,cilcle,color,level,startAngle,endAngle,angle;
  3. x= this.w/ 2;y= this.h/ 2,tx=ty= 0;
  4. for( var i= 0;i< 6;i++){
  5. startAngle = i* 2* Math.PI/ 6,
  6. endAngle = (i+ 1)* 2* Math.PI/ 6,
  7. color=i% 2== 0? '#FFEAB1': '#FFFFFF';
  8. cilcle = new _.Circle({
  9. x:x, //圆心X坐标
  10. y:y, //圆心X坐标
  11. r:y -26, //半径
  12. startAngle:startAngle, //开始角度
  13. endAngle:endAngle, //结束角度
  14. fill: true,
  15. fillStyle:color
  16. });
  17. cilcle.level=i;
  18. this.renderArr.push(cilcle);
  19. this.cardArr.push(cilcle);
  20. }
  21. }

此时绘制效果:

绘制选项卡对应的图片

每次旋转60度放置图片、跟绘制奖项卡差不多,需要注意的时候绘制图片的时候,x、y均要做适量的偏移(代码中的 disX=60,disY=20)


  
  1. //绘制选项图片
  2. zhuanPan.prototype.drawCardImage=function(){
  3. 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;
  4. var arr=[ 4, 10, 5, 10, 6, 10]; //图片位置数组(这是根据加载图片存储的下标来写的)
  5. for(var i= 0;i< 6;i++){
  6. angle = i* -60;
  7. image = this.imgObj[arr[i]];
  8. 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});
  9. this.renderArr.push(img);
  10. this.cardImageArr.push(img);
  11. }
  12. }

绘制指针

1.绘制一个小圆,跟图片大小差不多,用来判断鼠标移入指针事件和鼠标点击指针事件。

2.绘制图片时,x、y的渲染位置要做一些偏移,不在圆心位置,因为图片的绘制和圆的绘制有一些差别。


  
  1. //绘制指针
  2. zhuanPan.prototype.drawPointer=function(){
  3. var x= this.w/ 2;y= this.h/ 2+ 7;
  4. var pointerCilcle = new _.Circle({
  5. x:x, //圆心X坐标
  6. y:y, //圆心X坐标
  7. r: 24, //半径
  8. startAngle: 0, //开始角度
  9. endAngle: 2*Math.PI, //结束角度
  10. fill: true,
  11. fillStyle: "red"
  12. });
  13. this.renderArr.push(pointerCilcle);
  14. this.pointerObj=pointerCilcle;
  15. var image = this.imgObj[ 11];
  16. x=y= 0;
  17. var img,sWidth= 64,sHeight= 64,dx= this.w/ 2- 32,dy= this.h/ 2- 32,dWidth= 64,dHeight= 64;
  18. img = new _.ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight});
  19. this.renderArr.push(img);
  20. }

绘制外围修饰的小圆


  
  1. //装饰灯
  2. zhuanPan.prototype.drawLight= function(){
  3. var x=y=r= 0,cilcle,color,level,startAngle,endAngle,angle;
  4. x= this.w/ 2;y= this.h/ 2,tx=ty= 0;
  5. for( var i= 0;i< 12;i++){
  6. color=i% 2== 0? '#FDFEC1': '#FEFCFB';
  7. r=i% 2== 0? 4: 6;
  8. cilcle = new _.Circle({
  9. x:x, //圆心X坐标
  10. y:y, //圆心X坐标
  11. r:r, //半径
  12. disX: 170, //x方向偏移
  13. startAngle: 0, //开始角度
  14. endAngle: 2* Math.PI, //结束角度
  15. fill: true,
  16. fillStyle:color,
  17. angle:i* -30
  18. });
  19. cilcle.level=i;
  20. this.renderArr.push(cilcle);
  21. this.lightArr.push(cilcle);
  22. }
  23. }

页面的绘制已经完成了,看起来还不错呢。

 接下来加入鼠标事件 

鼠标移动事件

判断是鼠标的位置,是否处于指针位置的小圆范围内,如果在鼠标就变成手的形状,否则鼠标就普通的形状。


  
  1. //鼠标移动事件
  2. zhuanPan.prototype.mouseMove=function(e){
  3. var pos = _.getOffset(e); //获取鼠标位置
  4. var isCatch = this.pointerObj.isPoint(pos); //鼠标捕捉
  5. if(isCatch){
  6. this.el.style.cursor = 'pointer'; //改为手状形态
  7. } else{
  8. this.el.style.cursor = '';
  9. }
  10. }

鼠标点击事件

1.开启定时任务,每次以10度的角度来旋转;

2.随机一个范围0-360的角度,默认旋转2圈,2圈之后再旋转刚才随机出来的角度,待随机的角度旋转到位后,停止旋转,然后判断中奖情况;

3.判断指针的角度在哪个奖项卡的开始和结束角度内,则确定中奖情况。


  
  1. //转动
  2. zhuanPan.prototype.rotate= function(){
  3. var that= this;
  4. doUpdate.call(that);
  5. function doUpdate(){
  6. var flag= false;
  7. _.each(that.cardArr, function(item){
  8. //角度旋转
  9. item.angle -= 10;
  10. if(that.catchStartFlag){
  11. //因为到-360度是时候就会重置为0
  12. if(item.level== 0 && item.angle<=-that.endRandomAngle){
  13. that.catchStartFlag= false;
  14. clearInterval(that.timmer);
  15. that.timmer= null;
  16. that.timeCount= 0;
  17. that.cardCatch();
  18. }
  19. }
  20. //达到最大角度则重置角度
  21. if(item.angle<= -360){
  22. item.angle= 360+item.angle;
  23. if(!flag){
  24. that.timeCount++;
  25. flag= true;
  26. }
  27. }
  28. });
  29. _.each(that.cardImageArr, function(item){
  30. //角度旋转
  31. item.angle -= 10;
  32. //达到最大角度则重置角度
  33. if(item.angle<= -360){
  34. item.angle= 360+item.angle;
  35. }
  36. });
  37. _.each( this.lightArr, function(item,i){
  38. //角度旋转
  39. item.angle -= 10;
  40. //达到最大角度则重置角度
  41. if(item.angle<= -360){
  42. item.angle= 360+item.angle;
  43. }
  44. })
  45. this.render();
  46. }
  47. if(that.timeCount== 2){ //进入捕获阶段
  48. that.catchStartFlag= true;
  49. }
  50. }
  51. //中奖捕获
  52. zhuanPan.prototype.cardCatch= function(){
  53. var catchAngle= 270- this.endRandomAngle; //中奖捕获角度
  54. catchAngle = catchAngle< 0?catchAngle+ 360:catchAngle;
  55. var max ,min,levelArr= this.levelArr;
  56. var that= this;
  57. _.each( this.cardArr, function(item){
  58. min = item.startAngle* 180/ Math.PI ;
  59. max = item.endAngle* 180/ Math.PI ;
  60. if(catchAngle>min && catchAngle<max){
  61. var result = levelArr[item.level];
  62. console.log( "result=="+result);
  63. setTimeout( function(){
  64. alert(result)
  65. }, 100)
  66. }
  67. })
  68. }

代码就完成了

源码下载

方式1:少量积分,下载代码

方式2:关注下方公众号,回复 125 下载代码

 更多源码

 ♥ 基于canvas的手风琴特效(附源码)♥

♥ 抖音很火的华为太空人表盘(附源码)♥

♥ 基于JavaScript页面动态验证码(附源码)♥

♥ 基于JavaScript的拖动滑块拼图验证(附源码)♥

♥ 基于JavaScript的幸运大转盘(附源码)♥

♥ 抖音很火的罗盘时钟(附源码)♥

♥ 基于JavaScript的俄罗斯方块小游戏(附源码)♥

♥ 基于JavaScript的贪吃蛇游戏(附源码)♥

♥ 基于JavaScript的拼图游戏(附源码)♥

♥ 用JavaScript给女儿做的烟花特效(附源码)♥

♥ 老父亲给女儿做的下雪特效,满足女儿看雪的愿望(附源码)♥

♥ 雷达扫描特效(附源码)♥

♥ 香港黄金配角吴孟达去世,80后程序员以轮播图来悼念达叔,达叔一路走好!(附源码)♥

♥ 仿抖音刷新进度条(附源码)♥

♥ 仿头条方形刷新进度条(附源码)♥

♥ 仿360加速球、水波评分特效(附源码)♥

♥ 基于canvas的刮刮卡(附源码)♥

♥ 原生js写的左侧飞入拼图特效,你是喜欢美女单飞还是双飞(附源码)♥

♥ 用js写的旋转木马,在新年献给各位刚登基的皇帝,让你的后宫转起来!程序员就是可以为所欲为!(附源码)♥

♥ 用js写的轮播图,八位女明星,你翻谁的牌,程序员就是可以为所欲为!(附源码)♥

♥ 原生js实现美女拼图,把美女老婆抱回家,5个美女够不够!程序员就是可以为所欲为!(附源码)♥

♥ 用js仿探探拖拽卡片的效果、飞卡片的效果,感觉挺酷,最后有美女看哦!(附源码)♥

♥ 老婆说程序员不懂浪漫,程序员默默拿起了键盘,这就亲手带你去看流星雨,女人真的会影响拔刀的速度!(附源码)♥

♥ 学生成绩管理系统(jsp+jquery+java+mysql+tomcat)有源码,你的毕设我的心(附源码)♥


转载:https://blog.csdn.net/dkm123456/article/details/115457093
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场