上个案例转盘中的文字,绘制点是通过三角函数精确计算后绘制的,本方案中的文字,没有使用三角函数,而是将文字在(0,0)点旋转后,再进行偏移实现,本案例逻辑上比较简洁。
<!DOCTYPE html><html lang=”en”>
<head> <meta charset=”UTF-8″> <meta http-equiv=”X-UA-Compatible” content=”IE=edge”> <meta name=”viewport” content=”width=device-width, initial-scale=1.0″> <title>Document</title> <style> .box { position: relative; }
/* 绘制箭头 */ .arrow { position: absolute; top: 165px; left: 200px; width: 4px; height: 40px; background-color: #000; cursor: pointer; }
.arrow::after { content: “”; display: block; position: absolute; top: -5px; left: -3px; width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 10px solid #000; } </style></head>
<body> <div class=”box”> <canvas id=”canvas”></canvas> <div class=”arrow”></div> </div> <script> /** @type {HTMLCanvasElement} */ let canvas = document.getElementById(“canvas”), arrow = document.getElementsByClassName(“arrow”)[0], ctx = canvas.getContext(‘2d’), width = 400,//canvas 宽度 height = 400,//canvas 高度 r = 200,//转盘宽度 rtext = 140,//文本围成的圆半径 startRadian = 0,//圆弧开始弧度数 endRadian = 0,//圆弧结束弧度数 prize = [“10元话费”, “20元话费”, “30元话费”, “40元话费”, “50元话费”, “60元话费”],//奖品 i = 1,//抽奖次数 flag = false,//正在抽奖中 angle = 360 / prize.length;//单个圆弧的角度数
canvas.width = width; canvas.height = height;
// 偏移画板,使用中心点作为(0,0)点 ctx.translate(width / 2, height / 2);
// 绘制转盘 prize.forEach((item, index) => { startRadian = Math.PI * 2 / prize.length * index; endRadian = Math.PI * 2 / prize.length * index + Math.PI * 2 / prize.length; turntable(item, index); })
// 绘制一个圆弧 function turntable(item, index) { ctx.save(); ctx.beginPath(); ctx.moveTo(0, 0); ctx.fillStyle = index % 2 == 0 ? “rgba(0,0,0,0.2)” : “rgba(0,0,0,0.1)”; ctx.arc(0, 0, r, startRadian, endRadian) ctx.fill(); ctx.closePath(); ctx.restore();
ctx.save(); ctx.beginPath(); ctx.font = “14px 微软雅黑”; ctx.textBaseline = “middle”; // 首先将文字在(0,0)基点做对应角度的旋转 ctx.rotate(Math.PI / 180 * (120 + index * angle)); // 在(0,0)基点的基础上,对所有的文本进行偏移 ctx.translate(0, -100) ctx.fillText(item, -ctx.measureText(item).width / 2, 0); ctx.closePath(); ctx.restore(); }
// 点击抽奖 arrow.addEventListener(“click”, function () { if (flag) return; flag = true; let x = Math.floor(Math.random() * prize.length), deg = 3600 * i + (180 + angle – x * angle + (prize.length % 4 == 0 ? angle / 2 : 0)); canvas.style.transition = “all 6s cubic-bezier(0, 0.98,0.99, 1)” canvas.style.transform = “rotate(” + deg + “deg)”; i++; setTimeout(() => { console.log(x + 1) flag = false; }, 6000); }) </script></body>
</html>
网上找的很多都是基于三角函数的解决方案,我也手码了一份,具体可以参考:三角函数方案:canvas转盘抽奖互动小游戏源码,附带效果
Nice post. I learn something new and challenging on sites I stumbleupon on a daily basis. Its always helpful to read through articles from other writers and use something from their web sites.