首页 / CANVAS / canvas转盘抽奖的实现(一)
canvas转盘抽奖的实现(一)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了canvas转盘抽奖的实现(一),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7912字,纯文字阅读大概需要12分钟。
内容图文
网络上已经有了很多转盘抽奖的代码,但大多是用jQuery插件实现的,其中的原理比较难弄明白,于是自己摸索了一个。最终效果如下:
实现步骤:
1.根据奖品数量绘制转盘
var r1 = 200, //外圆半径 r2 = 160, //奖品文字距离圆心的位置 r3 = 60, //中心按钮半径 centerX = c.width / 2, //中点 centerY = c.height / 2, PI = Math.PI, prizeList = [‘一等奖‘,‘二等奖‘,‘三等奖‘,‘四等奖‘,‘五等奖‘,‘六等奖‘,‘七等奖‘,‘八等奖‘], //奖品列表 colorList = [‘#ffffff‘,‘#FDFAC3‘,‘#ffffff‘,‘#FDFAC3‘,‘#ffffff‘,‘#FDFAC3‘,‘#ffffff‘,‘#FDFAC3‘], //奖品对应的背景颜色 lenPrize = prizeList.length,
startAngle = 0, //开始绘制时的起始角度 piece = 2 * PI / lenPrize; //根据奖品数量划分区域,单位为弧度
// 绘制分区 for (var i = 0; i < lenPrize; i++) { ctx.fillStyle = colorList[i]; var angle = startAngle + piece * i; ctx.beginPath(); //设置圆心为起点,方便closePath()自动闭合路径 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(); }
这一部分代码的效果如下:
图一
要注意首个奖品说明的位置,也就是一等奖的位置,是从三点钟方向开始的,这是arc()方法的规定,下面这张图表示从1到N按顺序绘制。
图二
接下来绘制箭头和中心圆:
// 绘制箭头 ctx.strokeStyle = ‘#FF5722‘; ctx.fillStyle = ‘#FF5722‘; ctx.save(); ctx.translate(centerX, centerY - 40); ctx.moveTo( - 10, 0); ctx.beginPath(); ctx.lineTo( - 10, 0); ctx.lineTo( - 10, -30); ctx.lineTo( - 20, -30); ctx.lineTo(0, -50); ctx.lineTo(20, -30); ctx.lineTo(10, -30); ctx.lineTo(10, 0); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.restore(); //绘制中心圆 ctx.fillStyle = ‘#FF5722‘; ctx.beginPath(); ctx.arc(centerX, centerY, r3, 0, 2 * PI, false); ctx.closePath(); ctx.fill(); ctx.stroke(); //绘制抽奖文字 ctx.font = ‘30px Microsoft YaHei‘; ctx.fillStyle = ‘#fff‘; ctx.save(); ctx.translate(centerX, centerY); ctx.fillText("抽奖", -ctx.measureText(text).width, 10); ctx.restore();
这就是最终效果
最后实现转盘的转动,先定义几个变量:
var currentTime = 0, //表示动画开始到现在持续的时间 totalTime = Math.random() * 500 + 4000, //动画总时间
finalValue = Math.random() * 20 + 20,//动画总时间内期望的位移总量,越大转得越快,因为总时间一定,只有加快速度才能在规定时间内到达期望位移
t; //setTimeout Id
转盘转动方法:
function rotation() { currentTime += 30; //每帧增加30的运行时间if (currentTime >= totalTime) {//到达总时间后停止动画 stopRotation(); return; } //缓动var currentAngle = finalValue - easeOut(currentTime, 0, finalValue, totalTime); //弧度随时间递增,但增速由快变慢 startAngle += currentAngle * PI / 180; //根据startAngle的变化重新绘制转盘,以达到转动的效果 draw(); t = setTimeout(rotation, 17); }
停止转盘:
function stopRotation() { clearTimeout(t); // 动画时间内转动的总弧度,因为是从三点钟方向开始绘制的,所以应当加上PI/2 var arc = startAngle + PI / 2, //arc模2*PI以计算转动整圈以外不满一圈的零数//零数除以单位弧度,表示转动了几个单位,不满整数则向下取整(Math.floor)//奖品数量(以下标算,故先减1)减去转动过的单位得到当前指针所指奖品的索引 index = lenPrize - 1 - ((arc % (2 * PI) / piece) >> 0); result.innerHTML = ‘<strong style="font-size:26px; color:#f00">‘ + prizeList[index] + ‘</strong>‘; }
全部代码:
1 < !DOCTYPE html > 2 < html lang = "en" > 3 < head > 4 < meta charset = "UTF-8" > 5 < title > Document </title> 6<style> 7 body{margin: 0; font:12px Arial; background-color: #fff} 8 .canvas_container{ 9 position: relative; 10 width: 500px; 11 height: 500px; 12} 13 #run{ 14 position: absolute; 15 width: 120px; 16 height: 120px; 17 cursor: pointer; 18 left: 190px; 19 top: 190px; 20} 21</style ></head> 22<body> 23<div class="canvas_container"> 24<div id="run"></div ><canvas id = "c"width = "500"height = "500"></canvas> 25</div ><div id = "result"></div> 26 27<script> 28var c = document.getElementById(‘c‘), 29 ctx = c.getContext("2d"), 30 r1 =200, // 外圆半径r2 =160, 31//文字所在位置半径 32r3 =60, 33//中心按钮 34centerX = c.width /2, 35//中点 36centerY = c.height /2, 37PI = Math.PI; 38 39var prizeList = [‘一等奖‘, ‘二等奖‘, ‘三等奖‘, ‘四等奖‘, ‘五等奖‘, ‘六等奖‘, ‘七等奖‘, ‘八等奖‘], 40colorList = [‘#ffffff‘, ‘#FDFAC3‘, ‘#ffffff‘, ‘#FDFAC3‘, ‘#ffffff‘, ‘#FDFAC3‘, ‘#ffffff‘, ‘#FDFAC3‘], 41lenPrize = prizeList.length, 42lenColor = colorList.length, 43piece =2* PI / lenPrize, 44//根据奖品数量划分区域,单位弧度 45startAngle =0; //起始角度 46function draw() { 47 ctx.clearRect(0, 0, c.width, c.height); 48 49 ctx.lineWidth =0.5; 50 ctx.strokeStyle =‘#AF4760‘; 51 52//绘制分区 53for (var i =0; i < lenPrize; i++) { 54 ctx.fillStyle = colorList[i]; 55var angle = startAngle + piece * i; 56 ctx.beginPath(); 57 ctx.moveTo(centerX, centerY); 58//分块绘制,目的是方便填充颜色,如果以lineTo的形式绘制,在填充颜色时会很麻烦 59 ctx.arc(centerX, centerY, r1, angle, angle + piece, false); 60 ctx.closePath(); 61 ctx.fill(); 62 ctx.stroke(); 63 64//绘制奖品说明 65 ctx.save(); 66 ctx.font =‘30px Microsoft YaHei‘; 67 ctx.fillStyle =‘#d60000‘; 68 ctx.translate(centerX + Math.cos(angle + piece /2) * r2, centerY + Math.sin(angle + piece /2) * r2); 69 ctx.rotate(angle + piece /2+ PI /2); 70 71var s = prizeList[i].split(‘‘); 72for (var j =0; j < s.length; j++) { 73var text = s[j]; 74 ctx.fillText(text, -ctx.measureText(text).width /2, 32* j); 75 } 76 ctx.restore(); 77 } 78 79//绘制箭头 80 ctx.strokeStyle =‘#FF5722‘; 81 ctx.fillStyle =‘#FF5722‘; 82 ctx.save(); 83 ctx.translate(centerX, centerY -40); 84 ctx.moveTo( -10, 0); 85 ctx.beginPath(); 86 ctx.lineTo( -10, 0); 87 ctx.lineTo( -10, -30); 88 ctx.lineTo( -20, -30); 89 ctx.lineTo(0, -50); 90 ctx.lineTo(20, -30); 91 ctx.lineTo(10, -30); 92 ctx.lineTo(10, 0); 93 ctx.closePath(); 94 ctx.fill(); 95 ctx.stroke(); 96 ctx.restore(); 97 98//绘制中心圆 99 ctx.fillStyle =‘#FF5722‘; 100 ctx.beginPath(); 101 ctx.arc(centerX, centerY, r3, 0, 2* PI, false); 102 ctx.closePath(); 103 ctx.fill(); 104 ctx.stroke(); 105106//绘制抽奖文字107 ctx.font =‘30px Microsoft YaHei‘; 108 ctx.fillStyle =‘#fff‘; 109 ctx.save(); 110 ctx.translate(centerX, centerY); 111 ctx.fillText("抽奖", -ctx.measureText(text).width, 10); 112 ctx.restore(); 113114} 115116var currentTime =0, 117totalTime = Math.random() *500+4000, 118finalValue = Math.random() *20+20, 119//终点值120t; 121122function rotation() { 123 currentTime +=30; 124if (currentTime >= totalTime) { 125 stopRotation(); 126return; 127 } 128129var currentAngle = finalValue - easeOut(currentTime, 0, finalValue, totalTime); 130131//弧度随时间递增,但增速由快变慢132 startAngle += currentAngle * PI /180; 133 draw(); 134135 t = setTimeout(rotation, 17); 136} 137138function stopRotation() { 139 clearTimeout(t); 140141var arc = startAngle + PI /2, 142 index = lenPrize -1- ((arc % (2* PI) / piece) >>0); 143144 result.innerHTML =‘<strong style="font-size:26px; color:#f00">‘+ prizeList[index] +‘</strong>‘; 145} 146draw(); 147//rotation();148var run = document.getElementById(‘run‘), 149result = document.getElementById(‘result‘); 150run.onclick =function() { 151 currentTime =0; 152 totalTime = Math.random() *500+4000; 153 finalValue = Math.random() *20+20; 154 rotation(); 155}; 156157/*158 t: current time(当前时间) 159 b: beginning value(初始值) 160 c: change in value(变化总量) 161 d: duration(持续时间) 162*/163function easeOut(t, b, c, d) { 164return- c * (t /= d) * (t - 2) + b;165} 166167</script>168</body >169</html>
原文:http://www.cnblogs.com/undefined000/p/canvas-turntable.html
内容总结
以上是互联网集市为您收集整理的canvas转盘抽奖的实现(一)全部内容,希望文章能够帮你解决canvas转盘抽奖的实现(一)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。