IOS美区账号微信: springsunshine2017

前端技术 · 2021年6月25日 1

非三角函数方案实现canvas转盘抽奖小游戏,源码和demo

上个案例转盘中的文字,绘制点是通过三角函数精确计算后绘制的,本方案中的文字,没有使用三角函数,而是将文字在(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转盘抽奖互动小游戏源码,附带效果