当前位置: 移动技术网 > IT编程>开发语言>JavaScript > js抽奖转盘实现方法分析

js抽奖转盘实现方法分析

2020年06月23日  | 移动技术网IT编程  | 我要评论

九天音乐网站,爱相约,麦博雅皮士

本文实例讲述了js抽奖转盘实现方法。分享给大家供大家参考,具体如下:

 html  这里.left 固定了圆的宽度和高度,还有canvas也设置了固定宽高 绘制圆心的坐标也就出来了 (203,203)

抽奖转盘是由一个大圆和一个内圆完成 ;大圆负责绘制上奖品 ,内圆负责确定指针的位置,指针直接使用图片,决定位置确定

<div class="left">

<div class="turnplate" style="background:#1bacff;border-radius: 50%">
<canvas class="item" id="wheelcanvas" width="406px" height="406px"></canvas>
<img class="pointer" src="sp2/point.png"/>
</div>

</div>

外圆留空多少的问题

ps里查看间距是多少,此处圆心(203,203) 大圆的半径就是203-10 =193

这个数值在下图里设置

js

 <script type="text/javascript">
    var turnplate={
      restaraunts:[],				//大转盘奖品名称
      colors:[],					//大转盘奖品区块对应背景颜色
      outsideradius:193,			//大转盘外圆的半径 192
      textradius:155,				//大转盘奖品位置距离圆心的距离
      insideradius:68,			//大转盘内圆的半径
      startangle:0,				//开始角度

      brotate:false				//false:停止;ture:旋转
    };

    $(document).ready(function(){
      //动态添加大转盘的奖品与奖品区域背景颜色
      turnplate.restaraunts = ["50元代金券", "升职加薪", "100元代金券", "财源滚滚", "200元代金券", "爱情甜蜜 ", "500元代金券", "变美变帅"];
      turnplate.colors = ["#1b62ca", "#1bacff", "#1b62ca", "#1bacff","#1b62ca", "#1bacff", "#1b62ca", "#1bacff"];


      var rotatetimeout = function (){
        $('#wheelcanvas').rotate({
          angle:0,
          animateto:2160,
          duration:8000,
          callback:function (){
            alert('网络超时,请检查您的网络设置!');
          }
        });
      };

      //旋转转盘 item:奖品位置; txt:提示语;
      var rotatefn = function (item, txt){
        var angles = item * (360 / turnplate.restaraunts.length) - (360 / (turnplate.restaraunts.length*2));
        if(angles<270){
          angles = 270 - angles;
        }else{
          angles = 360 - angles + 270;
        }
        $('#wheelcanvas').stoprotate();
        $('#wheelcanvas').rotate({
          angle:0,
          animateto:angles+1800,
          duration:8000,
          callback:function (){
            alert(txt);
            turnplate.brotate = !turnplate.brotate;
          }
        });
      };

      $('.pointer').click(function (){
        if(turnplate.brotate)return;
        turnplate.brotate = !turnplate.brotate;
        //获取随机数(奖品个数范围内)
        var item = rnd(1,turnplate.restaraunts.length);
        //奖品数量等于10,指针落在对应奖品区域的中心角度[252, 216, 180, 144, 108, 72, 36, 360, 324, 288]
        rotatefn(item, turnplate.restaraunts[item-1]);
        /* switch (item) {
         case 1:
         rotatefn(252, turnplate.restaraunts[0]);
         break;
         case 2:
         rotatefn(216, turnplate.restaraunts[1]);
         break;
         case 3:
         rotatefn(180, turnplate.restaraunts[2]);
         break;
         case 4:
         rotatefn(144, turnplate.restaraunts[3]);
         break;
         case 5:
         rotatefn(108, turnplate.restaraunts[4]);
         break;
         case 6:
         rotatefn(72, turnplate.restaraunts[5]);
         break;
         case 7:
         rotatefn(36, turnplate.restaraunts[6]);
         break;
         case 8:
         rotatefn(360, turnplate.restaraunts[7]);
         break;
         case 9:
         rotatefn(324, turnplate.restaraunts[8]);
         break;
         case 10:
         rotatefn(288, turnplate.restaraunts[9]);
         break;
         } */
        console.log(item);
      });
    });

    function rnd(n, m){
      var random = math.floor(math.random()*(m-n+1)+n);
      return random;

    }


    //页面所有元素加载完毕后执行drawroulettewheel()方法对转盘进行渲染
    window.onload=function(){
      drawroulettewheel();
    };

    function drawroulettewheel() {
      var canvas = document.getelementbyid("wheelcanvas");
      if (canvas.getcontext) {
        //根据奖品个数计算圆周角度
        var arc = math.pi / (turnplate.restaraunts.length/2);//圆周率/ 奖品数量除以2
        var ctx = canvas.getcontext("2d");
        //在给定矩形内清空一个矩形
        ctx.clearrect(0,0,422,422);
        //strokestyle 属性设置或返回用于笔触的颜色、渐变或模式
        ctx.strokestyle = "#ffbe04";
        //font 属性设置或返回画布上文本内容的当前字体属性
        ctx.font = '16px microsoft yahei';
        // 绘制圆 (弧形)
        for(var i = 0; i < turnplate.restaraunts.length; i++) {
          var angle = turnplate.startangle + i * arc;
          ctx.fillstyle = turnplate.colors[i];
          ctx.beginpath();
          //arc(x,y,r,起始角,结束角,绘制方向) 方法创建弧/曲线(用于创建圆或部分圆)
          ctx.arc(203, 203, turnplate.outsideradius, angle, angle + arc, false);//绘制外圆
          ctx.arc(203, 203, turnplate.insideradius, angle + arc, angle, true);//绘制内圆
          ctx.stroke();
          ctx.fill();
          //锁画布(为了保存之前的画布状态)
          ctx.save();

          //----绘制奖品开始----
          ctx.fillstyle = "#fff";/*奖品文字颜色*/
          var text = turnplate.restaraunts[i];
          var line_height = 17;
          //translate方法重新映射画布上的 (0,0) 位置
          ctx.translate(211 + math.cos(angle + arc / 2) * turnplate.textradius, 211 + math.sin(angle + arc / 2) * turnplate.textradius);

          //rotate方法旋转当前的绘图
          ctx.rotate(angle + arc / 2 + math.pi / 2);

          /** 下面代码根据奖品类型、奖品名称长度渲染不同效果,如字体、颜色、图片效果。(具体根据实际情况改变) **/
          if(text.indexof("m")>0){//流量包
            var texts = text.split("m");
            for(var j = 0; j<texts.length; j++){
              ctx.font = j == 0?'bold 20px microsoft yahei':'16px microsoft yahei';
              if(j == 0){
                ctx.filltext(texts[j]+"m", -ctx.measuretext(texts[j]+"m").width / 2, j * line_height);
              }else{
                ctx.filltext(texts[j], -ctx.measuretext(texts[j]).width / 2, j * line_height);
              }
            }
          }else if(text.indexof("m") == -1 && text.length>6){//奖品名称长度超过一定范围
            text = text.substring(0,6)+"||"+text.substring(6);
            var texts = text.split("||");
            for(var j = 0; j<texts.length; j++){
              ctx.filltext(texts[j], -ctx.measuretext(texts[j]).width / 2, j * line_height);
            }
          }else{
            //在画布上绘制填色的文本。文本的默认颜色是黑色
            //measuretext()方法返回包含一个对象,该对象包含以像素计的指定字体宽度
            ctx.filltext(text, -ctx.measuretext(text).width / 2, 0);
          }

          //添加对应图标
          if(text.indexof("闪币")>0){
            var img= document.getelementbyid("shan-img");
            img.onload=function(){
              ctx.drawimage(img,-15,10);
            };
            ctx.drawimage(img,-15,10);
          }else if(text.indexof("谢谢参与")>=0){
            var img= document.getelementbyid("sorry-img");
            img.onload=function(){
              ctx.drawimage(img,-15,10);
            };
            ctx.drawimage(img,-15,10);
          }
          //把当前画布返回(调整)到上一个save()状态之前
          ctx.restore();
          //----绘制奖品结束----
        }
      }
    }

  </script>

引用jquery

在加载以下js

/* ????????????? www.datouwang.com */
(function($) {
var supportedcss,styles=document.getelementsbytagname("head")[0].style,tocheck="transformproperty webkittransform otransform mstransform moztransform".split(" ");
for (var a=0;a<tocheck.length;a++) if (styles[tocheck[a]] !== undefined) supportedcss = tocheck[a];
// bad eval to preven google closure to remove it from code o_o
// after compresion replace it back to var ie = 'v' == '\v'
var ie = eval('"v"=="\v"');

jquery.fn.extend({
  rotate:function(parameters)
  {
    if (this.length===0||typeof parameters=="undefined") return;
      if (typeof parameters=="number") parameters={angle:parameters};
    var returned=[];
    for (var i=0,i0=this.length;i<i0;i++)
      {
        var element=this.get(i);	
        if (!element.wilq32 || !element.wilq32.photoeffect) {

          var paramclone = $.extend(true, {}, parameters); 
          var newrotobject = new wilq32.photoeffect(element,paramclone)._rootobj;

          returned.push($(newrotobject));
        }
        else {
          element.wilq32.photoeffect._handlerotation(parameters);
        }
      }
      return returned;
  },
  getrotateangle: function(){
    var ret = [];
    for (var i=0,i0=this.length;i<i0;i++)
      {
        var element=this.get(i);	
        if (element.wilq32 && element.wilq32.photoeffect) {
          ret[i] = element.wilq32.photoeffect._angle;
        }
      }
      return ret;
  },
  stoprotate: function(){
    for (var i=0,i0=this.length;i<i0;i++)
      {
        var element=this.get(i);	
        if (element.wilq32 && element.wilq32.photoeffect) {
          cleartimeout(element.wilq32.photoeffect._timer);
        }
      }
  }
});

// library agnostic interface

wilq32=window.wilq32||{};
wilq32.photoeffect=(function(){

	if (supportedcss) {
		return function(img,parameters){
			img.wilq32 = {
				photoeffect: this
			};
      
      this._img = this._rootobj = this._eventobj = img;
      this._handlerotation(parameters);
		}
	} else {
		return function(img,parameters) {
			// make sure that class and id are also copied - just in case you would like to refeer to an newly created object
      this._img = img;

			this._rootobj=document.createelement('span');
			this._rootobj.style.display="inline-block";
			this._rootobj.wilq32 = 
				{
					photoeffect: this
				};
			img.parentnode.insertbefore(this._rootobj,img);
			
			if (img.complete) {
				this._loader(parameters);
			} else {
				var self=this;
				// todo: remove jquery dependency
				jquery(this._img).bind("load", function()
				{
					self._loader(parameters);
				});
			}
		}
	}
})();

wilq32.photoeffect.prototype={
  _setupparameters : function (parameters){
		this._parameters = this._parameters || {};
    if (typeof this._angle !== "number") this._angle = 0 ;
    if (typeof parameters.angle==="number") this._angle = parameters.angle;
    this._parameters.animateto = (typeof parameters.animateto==="number") ? (parameters.animateto) : (this._angle); 

    this._parameters.step = parameters.step || this._parameters.step || null;
		this._parameters.easing = parameters.easing || this._parameters.easing || function (x, t, b, c, d) { return -c * ((t=t/d-1)*t*t*t - 1) + b; }
		this._parameters.duration = parameters.duration || this._parameters.duration || 1000;
    this._parameters.callback = parameters.callback || this._parameters.callback || function(){};
    if (parameters.bind && parameters.bind != this._parameters.bind) this._bindevents(parameters.bind); 
	},
	_handlerotation : function(parameters){
     this._setupparameters(parameters);
     if (this._angle==this._parameters.animateto) {
       this._rotate(this._angle);
     }
     else { 
       this._animatestart();     
     }
	},

	_bindevents:function(events){
		if (events && this._eventobj) 
		{
      // unbinding previous events
      if (this._parameters.bind){
        var oldevents = this._parameters.bind;
        for (var a in oldevents) if (oldevents.hasownproperty(a)) 
            // todo: remove jquery dependency
            jquery(this._eventobj).unbind(a,oldevents[a]);
      }

      this._parameters.bind = events;
			for (var a in events) if (events.hasownproperty(a)) 
				// todo: remove jquery dependency
					jquery(this._eventobj).bind(a,events[a]);
		}
	},

	_loader:(function()
	{
		if (ie)
		return function(parameters)
		{
			var width=this._img.width;
			var height=this._img.height;
			this._img.parentnode.removechild(this._img);
							
			this._vimage = this.createvmlnode('image');
			this._vimage.src=this._img.src;
			this._vimage.style.height=height+"px";
			this._vimage.style.width=width+"px";
			this._vimage.style.position="absolute"; // fixes ie problem - its only rendered if its on absolute position!
			this._vimage.style.top = "0px";
			this._vimage.style.left = "0px";

			/* group minifying a small 1px precision problem when rotating object */
			this._container = this.createvmlnode('group');
			this._container.style.width=width;
			this._container.style.height=height;
			this._container.style.position="absolute";
			this._container.setattribute('coordsize',width-1+','+(height-1)); // this -1, -1 trying to fix ugly problem with small displacement on ie
			this._container.appendchild(this._vimage);
			
			this._rootobj.appendchild(this._container);
			this._rootobj.style.position="relative"; // fixes ie problem
			this._rootobj.style.width=width+"px";
			this._rootobj.style.height=height+"px";
			this._rootobj.setattribute('id',this._img.getattribute('id'));
			this._rootobj.classname=this._img.classname;			
		  this._eventobj = this._rootobj;	
		  this._handlerotation(parameters);	
		}
		else
		return function (parameters)
		{
			this._rootobj.setattribute('id',this._img.getattribute('id'));
			this._rootobj.classname=this._img.classname;
			
			this._width=this._img.width;
			this._height=this._img.height;
			this._widthhalf=this._width/2; // used for optimisation
			this._heighthalf=this._height/2;// used for optimisation
			
			var _widthmax=math.sqrt((this._height)*(this._height) + (this._width) * (this._width));

			this._widthadd = _widthmax - this._width;
			this._heightadd = _widthmax - this._height;	// widthmax because maxwidth=maxheight
			this._widthaddhalf=this._widthadd/2; // used for optimisation
			this._heightaddhalf=this._heightadd/2;// used for optimisation
			
			this._img.parentnode.removechild(this._img);	
			
			this._aspectw = ((parseint(this._img.style.width,10)) || this._width)/this._img.width;
			this._aspecth = ((parseint(this._img.style.height,10)) || this._height)/this._img.height;
			
			this._canvas=document.createelement('canvas');
			this._canvas.setattribute('width',this._width);
			this._canvas.style.position="relative";
			this._canvas.style.left = -this._widthaddhalf + "px";
			this._canvas.style.top = -this._heightaddhalf + "px";
			this._canvas.wilq32 = this._rootobj.wilq32;
			
			this._rootobj.appendchild(this._canvas);
			this._rootobj.style.width=this._width+"px";
			this._rootobj.style.height=this._height+"px";
      this._eventobj = this._canvas;
			
			this._cnv=this._canvas.getcontext('2d');
      this._handlerotation(parameters);
		}
	})(),

	_animatestart:function()
	{	
		if (this._timer) {
			cleartimeout(this._timer);
		}
		this._animatestarttime = +new date;
		this._animatestartangle = this._angle;
		this._animate();
	},
  _animate:function()
  {
     var actualtime = +new date;
     var checkend = actualtime - this._animatestarttime > this._parameters.duration;

     // todo: bug for animatedgif for static rotation ? (to test)
     if (checkend && !this._parameters.animatedgif) 
     {
       cleartimeout(this._timer);
     }
     else 
     {
       if (this._canvas||this._vimage||this._img) {
         var angle = this._parameters.easing(0, actualtime - this._animatestarttime, this._animatestartangle, this._parameters.animateto - this._animatestartangle, this._parameters.duration);
         this._rotate((~~(angle*10))/10);
       }
       if (this._parameters.step) {
        this._parameters.step(this._angle);
       }
       var self = this;
       this._timer = settimeout(function()
           {
           self._animate.call(self);
           }, 10);
     }

     // to fix bug that prevents using recursive function in callback i moved this function to back
     if (this._parameters.callback && checkend){
       this._angle = this._parameters.animateto;
       this._rotate(this._angle);
       this._parameters.callback.call(this._rootobj);
     }
   },

	_rotate : (function()
	{
		var rad = math.pi/180;
		if (ie)
		return function(angle)
		{
      this._angle = angle;
			this._container.style.rotation=(angle%360)+"deg";
		}
		else if (supportedcss)
		return function(angle){
      this._angle = angle;
			this._img.style[supportedcss]="rotate("+(angle%360)+"deg)";
		}
		else 
		return function(angle)
		{
      this._angle = angle;
			angle=(angle%360)* rad;
			// clear canvas	
			this._canvas.width = this._width+this._widthadd;
			this._canvas.height = this._height+this._heightadd;
						
			// remember: all drawings are read from backwards.. so first function is translate, then rotate, then translate, translate..
			this._cnv.translate(this._widthaddhalf,this._heightaddhalf);	// at least center image on screen
			this._cnv.translate(this._widthhalf,this._heighthalf);			// we move image back to its orginal 
			this._cnv.rotate(angle);										// rotate image
			this._cnv.translate(-this._widthhalf,-this._heighthalf);		// move image to its center, so we can rotate around its center
			this._cnv.scale(this._aspectw,this._aspecth); // scale - if needed ;)
			this._cnv.drawimage(this._img, 0, 0);							// first - we draw image
		}

	})()
}

if (ie)
{
wilq32.photoeffect.prototype.createvmlnode=(function(){
document.createstylesheet().addrule(".rvml", "behavior:url(#default#vml)");
		try {
			!document.namespaces.rvml && document.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
			return function (tagname) {
				return document.createelement('<rvml:' + tagname + ' class="rvml">');
			};
		} catch (e) {
			return function (tagname) {
				return document.createelement('<' + tagname + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
			};
		}
})();
}
})(jquery);

感兴趣的朋友可以使用在线html/css/javascript代码运行工具: 测试上述代码运行效果。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网