1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > js+php+大转盘 H5 Canvas抽奖大转盘代码实现及总结

js+php+大转盘 H5 Canvas抽奖大转盘代码实现及总结

时间:2020-06-18 23:17:47

相关推荐

js+php+大转盘 H5 Canvas抽奖大转盘代码实现及总结

最近项目上写了一个签到页面,放在h5、ios和安卓中一起用 ,其中有一个功能是抽奖大转盘,这是一个很常用的功能,现在总结记录一下:

效果gif

需求

1、每种奖品的中奖概率由后台确定,非随机。

2、页面上大转盘中的奖品图品和名称有后台提供,灵活非静态。

技术栈

1、HTML5 Canvas

2、引用Jquery插件jQueryRotate.js

踩坑和注意

1、绘制后的画布文字模糊,画布设置尺寸后,css将其设置为一半大小,如此就相当于画了一张200*400的图片,然后设置他显示成100*200的大小,这样一来就变得清晰了。需要注意的是,这样将画布放大之后,绘制的过程中对应的那些坐标,长度等等都要相应的放大

2、canvas加载奖品图片,全都堆叠在左上角,原因是绘制画布时图片还没加载出来,需要使用onload解决

//注意需要等图片加载完成后绘制

window.onload = function() {

drawWheelCanvas();

};

3、ios的Webview ajax不兼容,因为当时是本地作为服务器测试的,部署在服务器上就行了。参考

4、save()与restore()区别

save表示保存save函数之前的状态;restore表示获取save保存的状态

5、canvas是从水平位置开始绘制的

6、实现转盘四周闪烁效果,其实就是两张图片的切换,如图

两张图片的切换

四周闪烁效果.gif

具体代码

第一步:HTML布局

第二部:绘制大转盘

做一些画布的基础设置,此处预先假设抽奖奖项为6项

//获取canvas画布

var canvas = document.getElementById("wheelCanvas");

var ctx = canvas.getContext("2d");

var canvasW = canvas.width; // 画板的高度

var canvasH = canvas.height; // 画板的宽度

//计算每个奖项所占角度数

var baseAngle = Math.PI * 2 / 6;

ctx.clearRect(0,0,canvasW,canvasH);//去掉背景默认的黑色

console.log(canvasW);

ctx.strokeStyle = "#199301"; //设置画图线的颜色

ctx.font = '26px Microsoft YaHei';//设置字号字体

循环绘制6个60度的扇形,canvas是从水平位置开始绘制的,效果如图

colors = ["#AE3EFF","#4D3FFF","#FC262C","#3A8BFF","#EE7602","#FE339F"];

for(var index = 0; index < 6; index++) {

var angle = index * baseAngle;

ctx.fillStyle = colors[index];//设置每个扇形区域的颜色

ctx.beginPath();//开始绘制

ctx.arc(canvasW * 0.5, canvasH * 0.5, 170, angle, angle + baseAngle, false);

ctx.arc(canvasW * 0.5, canvasH * 0.5, 68, angle + baseAngle, angle, true);

//context.arc(x,y,r,sAngle,eAngle,counterclockwise);创建弧/曲线

ctx.stroke();//开始链线

ctx.fill();//填充颜色

ctx.save();//保存当前环境的状态

}

循环绘制6个60度的扇形,并放上文字图片

colors = ["#AE3EFF","#4D3FFF","#FC262C","#3A8BFF","#EE7602","#FE339F"];

rewardUrl =[]//从服务器请求回来的imgurl

prizeId =[]//从服务器请求回来的奖项

// 图片信息

var imgUrl1 = new Image();

imgUrl1.src = turnWheel.rewardUrl[0];

var imgUrl2 = new Image();

imgUrl2.src = turnWheel.rewardUrl[1];

var imgUrl3 = new Image();

imgUrl3.src = turnWheel.rewardUrl[2];

var imgUrl4 = new Image();

imgUrl4.src = turnWheel.rewardUrl[3];

var imgUrl5 = new Image();

imgUrl5.src = turnWheel.rewardUrl[4];

var imgUrl6 = new Image();

imgUrl6.src = turnWheel.rewardUrl[5];

//注意需要等图片加载完成后绘制

window.onload = function() {

drawWheelCanvas();

};

for(var index = 0; index < 6; index++) {

var angle = index * baseAngle;

ctx.fillStyle = colors[index];//设置每个扇形区域的颜色

ctx.beginPath();//开始绘制

ctx.arc(canvasW * 0.5, canvasH * 0.5, 170, angle, angle + baseAngle, false);

ctx.arc(canvasW * 0.5, canvasH * 0.5, 68, angle + baseAngle, angle, true);

//context.arc(x,y,r,sAngle,eAngle,counterclockwise);创建弧/曲线

ctx.stroke();//开始链线

ctx.fill();//填充颜色

ctx.save();//保存当前环境的状态

ctx.fillStyle = "#fff000";

var rewardName = prizeId[index];

var line_height = 24;

// translate方法重新映射画布上的 (0,0) 位置

var translateX = canvasW * 0.5 + Math.cos(angle + baseAngle / 2) * turnWheel.textRadius;

var translateY = canvasH * 0.5 + Math.sin(angle + baseAngle / 2) * turnWheel.textRadius;

ctx.translate(translateX, translateY);

// rotate方法旋转当前的绘图,因为文字适合当前扇形中心线垂直的!

// angle,当前扇形自身旋转的角度 + baseAngle / 2 中心线多旋转的角度 + 垂直的角度90°

ctx.rotate(angle + baseAngle / 2 + Math.PI / 2);

//设置文本位置,居中显示

ctx.fillText(rewardName, -ctx.measureText(rewardName).width / 2, 100);

//添加对应图标

if(index == 0){

ctx.drawImage(imgUrl1,-35,0,60,60);

}else if(index == 1){

ctx.drawImage(imgUrl2,-35,0,60,60);

}else if(index == 2){

ctx.drawImage(imgUrl3,-35,0,60,60);

}else if(index == 3){

ctx.drawImage(imgUrl4,-35,0,60,60);

}else if(index == 4){

ctx.drawImage(imgUrl5,-35,0,60,60);

}else{

ctx.drawImage(imgUrl6,-35,0,60,60);

}

ctx.restore(); //很关键,还原画板的状态到上一个save()状态之前

}

第三部:设置旋转转盘配置

//旋转转盘 item:奖品序号,从0开始的; txt:提示语 ,count 奖品的总数量;

var rotateFunc = function(item, tip, count) {

// 应该旋转的角度,旋转插件角度参数是角度制。

var baseAngle = 360 / count;

// 旋转角度 == 270°(当前第一个角度和指针位置的偏移量) - 奖品的位置 * 每块所占的角度 - 每块所占的角度的一半(指针指向区域的中间)

angles = 360 * 3 / 4 - (item * baseAngle) - baseAngle / 2; // 因为第一个奖品是从0°开始的,即水平向右方向

$('#wheelCanvas').stopRotate();

// 注意,jqueryrotate 插件传递的角度不是弧度制。

// 哪个标签调用方法,旋转哪个控件

$('#wheelCanvas').rotate({

angle: 0,

animateTo: angles + 360 * 5, // 这里多旋转了5圈,圈数越多,转的越快

duration: 8000,

callback: function() { // 回调

//弹出中奖提示

turnWheel.bRotate = !turnWheel.bRotate;

}

});

};

第四部:点击抽奖事件

此处需要做的是,在用户点击时向后台发送请求,接收中奖信息,开始旋转...

// 抽取按钮按钮点击触发事件

$('.pointer').click(function() {

// 正在转动,直接返回

if(turnWheel.bRotate) return;

turnWheel.bRotate = !turnWheel.bRotate;

var count = turnWheel.rewardNames.length;

$.ajax({

type: "POST",

url: "./drawPrize.htm",

data: {

customerId: $(".customerId").val()

},

async: false,

dataType: "json", // 返回数据类型

success: function(data) {

console.log(data);

if(data.type == 1) { //积分不足

} else if(data.type == 2) { //抽奖次数已经用完

} else { //抽奖次数已经用完

turnWheel.prizeId.forEach(function(currentValue, index) {

if(currentValue == data.prize.id) {

var item = index;

$(".award-warp .content").html(data.prize.name);

// 开始抽奖

rotateFunc(item, turnWheel.rewardNames[item], count);

}

})

}

},

error: function(data) {

console.log("网络错误,请检查您的网络设置!");

}

});

});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。