Among the projects I have done before, there are those who need the lottery turntable function. The project has been completed for a while and there are no serious bugs, so I will share it with you now.
Functional Requirements
1. The turntable should be beautiful and the rotation effect should be smooth.
2. The prize picture needs to be displayed on the turntable, and the prize is the photo and name read in the background.
3. After the rotation animation is completed, there must be corresponding prompts.
4. The specific algorithm for the obtained prize is operated in the database, and the front-end only provides the final effect display.
Key points of knowledge
1. A jq plug-in is referenced: awardRotate, which is used to achieve more intelligent rotation (plugin download: http://www.jqcool.net/jquery-jqueryrotate.html).
2. Use the canvas tag and the corresponding html5 api to operate. (Canvas Chinese manual can be viewed at http://javascript.ruanyifeng.com/htmlapi/canvas.html
text
Quote large turntable style
.lunck_draw_wrap{display:block;width:95%;margin-right:auto;} .lunck_draw_wrap .turnplate{display:block;width:106%; position:relative;} .lunck_draw_wrap .turnplate canvas.item{left:1px; position: relative; top:9px; width:100%;} .lunck_draw_wrap .turnplate img.pointer{ height:37.5%; left:34.6%; position: absolute; top:30%; width:31.5%;}Required parameters for turntable plug-in:
var turnplate ={ restaraunts:[],//Big turnplate prize name lucky:[],//Big turnplate content colors:[],//Big turnplate prize block corresponds to background color goodsimgArr:[],//Big turnplate picture page tag outsideRadius:175,//Radius of the outer circle of the large turnplate textRadius:140,//Distance of the prize position from the center of the circle insideRadius:65,//Radius of the inner circle of the large turnplate startAngle:0,//Start angle bRotate:false//False:Stop;ture:Rotate};From the parameters, we need to obtain the corresponding prize name, prize content, prize picture page label and other information from the server, and then render the large turntable.
So our first step is to send a request to the server to obtain the corresponding prize information and traverse it to the array parameters required to generate the large turntable:
$.each(data.list,function(key, value){ turnplate.restaraunts.push(value.data0); turnplate.lucky.push(value.data1); turnplate.goodsimgArr.push(getLuckyImg + value.data4); if(key %2==0) turnplate.colors.push("#fff"); else turnplate.colors.push("#5fcbd4"); })data.list is the json data I got:
[ { "data0":"First Prize", "data1":"iphone6s", "data2":"0", "data3":"0", "data4":"201510161406303384.png", "data5":"XXXX Network Technology", "data6":"XXXXXX, Kecheng District, Quzhou City, Zhejiang Province", "data7":"0570-XXXXXX" },...... ]Since the customer requires the prize to be "thank you for participating", the minimum prize is also "winning prize". So after traversing the prize, insert the rendering description of the "winning prize":
turnplate.goodsimgArr.push('../images/hongbao.png') turnplate.restaraunts.push("winner"); turnplate.colors.push("#5fcbd4"); // After all elements of the page are loaded, execute the drawRouletteWheel() method to render the turntable preloadimages(turnplate.goodsimgArr).done(function(images){ drawRouletteWheel(); });Because the image loading takes time, and copying the image using canvas requires the image to be loaded before it can be drawn, so I used preloadimages to render the large turntable after all the prize pictures are loaded:
//Preload function preloadimages(arr){ var newimages =[], loadedimages =0 var postaction =function(){}//A postaction function has been added here var arr =(typeof arr !="object")?[arr]: arr function imageloadpost(){ loadedimages++ if(loadedimages == arr.length){ postaction(newimages)//After loading, we call the postaction function and pass the newimages array as parameters} } for(var i =0; i < arr.length; i++){ newimages[i]=newImage() newimages[i].src = arr[i] newimages[i].onload =function(){ imageloadpost() } newimages[i].onerror =function(){ imageloadpost() } } return{//The done method of a blank object is returned here:function(f){ postaction = f || postaction } } }Draw the turntable code:
function drawRouletteWheel(){ var canvas = document.getElementById("wheelcanvas"); if(canvas.getContext){ //Calculate the circumferential angle based on the number of prizes var arc =Math.PI /(turnplate.restaraunts.length /2); var ctx = canvas.getContext("2d"); //Clear a rectangle in the given rectangle ctx.clearRect(0,0,422,422); //strokeStyle property sets or returns the color, gradient or pattern used for strokes ctx.strokeStyle ="rgba(0,0,0,0)"; //font Property settings or return the current font attribute of the text content on the canvas ctx.font ='bold 18px Microsoft YaHei'; for(var i =0; i < turnplate.restaraunts.length; i++){ // Calculate the drawn fan start radian based on the current prize index var angle = turnplate.startAngle + i * arc; // Draw the fan fill color according to the prize parameters ctx.fillStyle = turnplate.colors[i]; // Start drawing fan ctx.beginPath(); // Arc(x,y,r, start angle, end angle, draw direction) Method creates arc/curve (used to create circles or partial circles) // Draw large circle ctx.arc(212,212, turnplate.outsideRadius, angle, angle + arc,false); //Draw small circle ctx.arc(212,212, turnplate.insideRadius, angle + arc, angle,true); ctx.stroke(); ctx.fill(); //Lock the canvas (to save the previous canvas state) ctx.save(); //---Draw the prize start---- //Price default font color ctx.fillStyle ="#fff"; var text = turnplate.restaraunts[i]; var lukyname = turnplate.lucky[i]; var line_height =17; // Translate method remaps (0,0) on the canvas Position ctx.translate(212+Math.cos(angle + arc /2)* turnplate.textRadius,212+Math.sin(angle + arc /2)* turnplate.textRadius); //rotate method rotates the current drawing ctx.rotate(angle + arc /2+Math.PI /2); //Draw the prize picture var img =newImage(); img.src = turnplate.goodsimgArr[i]; ctx.drawImage(img,-17,35); //Because the designed turntable color blocks are interleaved, this can achieve different font colors in adjacent prize areas if(i %2==0){ ctx.fillStyle ="#f7452f"; } //Draw the font at the corresponding coordinate ctx.fillText(text,-ctx.measureText(text).width /2,0); //Set the font ctx.font =' 14px Microsoft YaHei'; //Draw the prize name if(text !="Winning Prize"){ ctx.fillText(lukyname,-ctx.measureText(lukyname).width /2,25); }else{ ctx.fillText("Youmai Coin",-ctx.measureText("Youmai Coin").width /2,25); } //Return the current canvas (insert) before the previous save() state ctx.restore(); ctx.save(); //------------------------------ } } }There are basically comments on each step. If you don’t understand the canvas method, you can use Baidu or query the Chinese manual I shared above.
The html code is:
<divclass="lunck_draw_wrap"> <divclass="turnplate"style=" background-size:100%100%;"> <canvasclass="item"id="wheelcanvas"width="422px"height="422px"></canvas> <imgclass="pointer"style="top:0px; left:0px; width:100%; height:100%;"src="../images/chouzhang12.png"/> <imgclass="pointer"src="../images/hianji .png"/> </div>
Reproduction image:
Click event to execute the code:
$('.lunck_draw_wrap').delegate("img.pointer","click",function(){ if(turnplate.bRotate)return; turnplate.bRotate =!turnplate.bRotate; $.getJSON("../AJAX/lottery.ashx","",function(data){ //1090 System configuration error, 1091 User not logged in or user data abnormal, 1092 User remaining points are insufficient, 1093 Unwinned hideInput("code",data.code) if(data.code.toString()=="1090"){ iosalet("system configuration error") }elseif(data.code.toString()=="1091"){ iosalet("User not logged in or user data exception") }elseif(data.code.toString()=="1092"){ iosalet("Under remaining points from the user") }elseif(data.code.toString()=="1094"){ iosalet("Over the number of draws per day") } else{ var upoint =0; upoint = parseInt($("#uPoint").html())- parseInt($("#sPoint").html()); $("#uPoint").html(upoint); if(data.isWin =='true'){ item = getArrayIndex(turnplate.restaraunts, data.name); rotateFn(item +1,"Congratulations for getting,"+ turnplate.restaraunts[item]); } else{ rotateFn(0,"Congratulations for winning the winning prize!"); } } } }) });The above code implements basic logic and also requires a method of turning the turntable to respond to the results transmitted from the server:
//Rotate the turntable item: Prize position; txt: prompt; var rotateFn = function(item, txt){ //Calculate the corresponding radian based on the number of the prizes transmitted var angles = item *(360/ turnplate.restaraunts.length)-(360/(turnplate.restaraunts.length *2)); if(angles <270){ angles =270- angles; }else{ angles =360- angles +270; } //Forcibly stop the turntable $('#wheelcanvas').stopRotate(); //Calculating the rotation method, setting the required parameters and callback function $('#wheelcanvas').rotate({ //Start angle angle:0, //The rotation angle +1800 is to turn a few more turns animateTo: angles +1800, duration:8000, callback:function(){ iosSuccess(txt); turnplate.bRotate =!turnplate.bRotate; if($("#code").val()!="1093"){ delayLoad(getHttpPrefix +"graphicdetails.html?lukyid="+ $("#code").val()) } } }); };OK, the main function codes have been shared, and some tools and methods are not understood. You can leave a message and I will add it.
Summarize
Canvas is a very powerful ace of HTML5 and can achieve many brilliant effects. I hope this article can help some friends who are learning to use canvas.