IOS美区账号微信: springsunshine2017

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

三角函数方案:canvas转盘抽奖互动小游戏源码,附带效果

先上源码:

<!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 微软雅黑”;
            // 计算出文本的初始偏移坐标            let x1 = Math.cos(Math.PI / 180 * (angle/2 + index * angle)) * rtext;            let y1 = Math.sin(Math.PI / 180 * (angle/2 + index * angle)) * rtext;
            // 处理居中问题,计算出初始坐标基础的偏移量            let x2 = Math.sin(Math.PI / 180 * (angle/2 + index * angle)) * ctx.measureText(item).width / 2;            let y2 = Math.cos(Math.PI / 180 * (angle/2 + index * angle)) * ctx.measureText(item).width / 2;
            // 使用最终的坐标偏移            ctx.translate(x1 + x2, y1 – y2)
            // 对偏移后的坐标进行旋转            ctx.rotate(Math.PI / 180 * (90+angle/2 + index * angle));
            ctx.fillText(item, 0, 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>

思路:

1、首先根据设置的奖品数量绘制转盘

2、使用数学中的三角函数计算出文本的偏移量以及旋转的角度

3、添加dom点击事件

4、使用css的transition 和transform属性设置转盘动画

5、计算出奖品的旋转角度

以上就是canvas转盘抽奖互动小游戏大概的思路,欢迎讨论~