您的位置:首页 > 其它

canvas转盘抽奖的实现(二)

2016-06-16 18:39 232 查看
  本篇是《canvas转盘抽奖的实现(一)》的另一种实现方法,主要通过css3的transform以及transition过渡来实现。

// (function() {
var canvas = document.createElement('canvas'),
a = document.getElementById('a');
canvas.id = 'c';
canvas.width = 500;
canvas.height = 500;

//a.appendChild(canvas);

var run = document.getElementById('run');
a.insertBefore(canvas,run);

var c = document.getElementById('c'),
ctx = c.getContext("2d"),
r1 = 200, //外圆半径
r2 = 160, //文字所在位置半径
r3 = 60, //中心按钮
centerX = c.width / 2, //中点
centerY = c.height / 2,
PI = Math.PI;

var prizeList = ['一等奖','二等奖','三等奖','四等奖','五等奖','六等奖','七等奖','八等奖'],
colorList = ['#ffffff','#FDFAC3','#ffffff','#FDFAC3','#ffffff','#FDFAC3','#ffffff','#FDFAC3'],
lenPrize = prizeList.length,
lenColor = colorList.length,
piece = 2 * PI / lenPrize, //根据奖品数量划分区域,单位弧度
startAngle = 0; //起始角度

function draw() {
ctx.clearRect(0, 0, c.width, c.height);

ctx.lineWidth = 0.5;
ctx.strokeStyle = '#AF4760';

//绘制分区
for(var i = 0; i < lenPrize; i++) {
ctx.fillStyle = colorList[i];
var angle = startAngle + piece * i;
ctx.beginPath();
ctx.moveTo(centerX, centerY);
//分块绘制,目的是方便填充颜色,如果以lineTo的形式绘制,在填充颜色时会很麻烦
ctx.arc(centerX, centerY, r1, angle, angle + piece, false);
ctx.closePath();
ctx.fill();
ctx.stroke();

//绘制奖品说明
ctx.save();
ctx.font = '30px Microsoft YaHei';
ctx.fillStyle = '#d60000';
ctx.translate(centerX + Math.cos(angle + piece / 2) * r2, centerY + Math.sin(angle + piece / 2) * r2);
ctx.rotate(angle + piece / 2 + PI / 2);

var s = prizeList[i].split('');
for(var j = 0; j < s.length; j++) {
var text = s[j];
ctx.fillText(text, -ctx.measureText(text).width / 2, 32 * j);
}
ctx.restore();
}
}

var data = {
1:{
prizeID:1,
rotate:2047.5
},
2:{
prizeID:2,
rotate:2002.5
},
3:{
prizeID:3,
rotate:1957.5
},
4:{
prizeID:4,
rotate:1912.5
},
5:{
prizeID:5,
rotate:1867.5
},
6:{
prizeID:6,
rotate:1822.5
},
7:{
prizeID:7,
rotate:1777.5
},
8:{
prizeID:8,
rotate:1732.5
}
};

function rotation() {
draw();
c.style.transition = 'all 3s ease-out';
c.style.transform = 'rotate('+ data[r].rotate +'deg)';
c.addEventListener('transitionend', stopRotation, false);
}

function stopRotation() {
flag = false;
result.innerHTML ='' + r + '等奖';
}
draw();

var run = document.getElementById('run'),
result = document.getElementById('result'),
r,
flag = false;

var num = { 1:[1,2,3], 2:[4,5,6,7,8], 3:[9,10,11,12,13,14,15], 4:[16,17,18,19,20,21,22,23,24,25], 5:[26,27,28,29,30,31,32,33,34,35,36,37], 6:[38,39,40,41,42,43,44,45,46,47,48,49,50,51], 7:[52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67], 8:[68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100] };
document.onselectstart = function() {
return false;
};
run.onclick = function() {
if(flag) return false;
flag = true;
r = (Math.random() * 100 + 1) >> 0;

for(var key in num) {
if(in_array(r,num[key])) {
r = key;
break;
}
}

c.style.transition = 'none';
c.style.transform = 'rotate(0)';
rotation();
};

function in_array(stringToSearch, arrayToSearch) {
for (s = 0; s < arrayToSearch.length; s++) {
thisEntry = arrayToSearch[s].toString();
if (thisEntry == stringToSearch) {
return true;
}
}
return false;
}
})();
// ]]>

  思路比较简单,事先规定好奖品待旋转的角度,然后通过rotate旋转。首先将奖品分为八组,每组记录待旋转的角度:

var data = {
1:{
prizeID:1,
rotate:2047.5
},
2:{
prizeID:2,
rotate:2002.5
},
3:{
prizeID:3,
rotate:1957.5
},
4:{
prizeID:4,
rotate:1912.5
},
5:{
prizeID:5,
rotate:1867.5
},
6:{
prizeID:6,
rotate:1822.5
},
7:{
prizeID:7,
rotate:1777.5
},
8:{
prizeID:8,
rotate:1732.5
}
};


点击抽奖按钮后执行旋转:

var r = Math.floor(Math.random() * 8 + 1);
function rotation() {
draw();
c.style.transition = 'all 3s ease-out';
c.style.transform = 'rotate('+ data[r].rotate +'deg)';
//监听transitionend,动画结束后触发事件
c.addEventListener('transitionend', stopRotation, false);
}

function stopRotation() {
result.innerHTML ='<strong style="font-size:30px; color:red">' + r + '等奖</strong>';
}


css3还是很强大的,只需要几行代码就能把复杂的动画完成。但这里的中奖概率与上一篇的概率均等有所不同,加入了权重:

var num = {
1:[1,2,3],
2:[4,5,6,7,8],
3:[9,10,11,12,13,14,15],
4:[16,17,18,19,20,21,22,23,24,25],
5:[26,27,28,29,30,31,32,33,34,35,36,37],
6:[38,39,40,41,42,43,44,45,46,47,48,49,50,51],
7:[52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67],
8:[68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]
};


选取100以内的随机数,观察它落在哪个区间,上述代码表示一等奖的概率只有3%,二等奖概率有5%。

r = (Math.random() * 100 + 1) >> 0;

for (var key in num) {
if (in_array(r, num[key])) {
r = key;
break;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: