Canvas打造三重玩法转盘:等分等概率转盘抽奖(2)

目录

前言

 效果图展示

​编辑

 一、localStorage和sessionStorage的区别

二、sessionStorage的使用

三、Canvas绘制转盘

四、完整代码

 效果图展示


前言

想象一下,你正置身于一个充满惊喜与刺激的世界,手中的转盘仿佛掌握着无尽的财富与好运。而今天,我们来看看等分等概率转盘。这种转盘的特点是每个区域都均等划分,每个区域的面积、形状都完全相同。无论是红色区域、蓝色区域还是绿色区域,它们都有着相同的概率被选中。当你轻轻一点,转盘飞速旋转,最终停留在哪个区域,完全取决于你的运气。这种等分转盘,简单直接,公平公正,是初学者们的最爱。

 效果图展示

 一、localStorage和sessionStorage的区别

localStorage和sessionStorage都是Web Storage API的一部分,用于在用户的浏览器上存储数据。

  1. 生命周期

    localStorage:数据没有过期时间,会一直存储在浏览器中,直到被手动删除或用户清除浏览器缓存。即使用户关闭浏览器或重启计算机,数据仍然会保留。②sessionStorage:数据只在当前浏览器窗口或标签页的生命周期内有效。当页面会话结束(例如,当用户关闭浏览器窗口或标签页)时,存储的数据就会被清除。如果页面重新打开,之前存储的数据将无法访问。
  2. 作用域

    localStorage:存储的数据在所有同源窗口中都是共享的。也就是说,如果你在一个标签页中修改了localStorage中的数据,那么在其他标签页中也能立即看到这些变化。
    • sessionStorage:存储的数据仅在当前窗口或标签页中有效。不同的窗口或标签页之间不会共享sessionStorage中的数据。
  3. 存储容量:localStorage和sessionStorage的存储容量都相对较大,通常可以达到5MB左右,但这取决于浏览器的实现。

二、sessionStorage的使用

sessionStorage和localStorage用法相同

1、 存储数据并获取

const key = 'sessionData';

const value = 'This data is stored in sessionStorage.';

sessionStorage.setItem(key, value);

const retrievedData = sessionStorage.getItem(key);

 2、移除或清空

// 使用removeItem方法从sessionStorage中删除数据

sessionStorage.removeItem(key);

// 使用clear方法清除sessionStorage中的所有数据

sessionStorage.clear();

三、Canvas绘制转盘

部分内容上一章已讲解,详情请看专栏上一章绘制转盘

Canvas打造三重玩法转盘:绘制转盘(1)icon-default.png?t=N7T8https://blog.csdn.net/weixin_63152500/article/details/137744545?spm=1001.2014.3001.5501

1、html、css部分内容

2、绘制转盘背景

3.转盘参数

const canvas = document.getElementById('rouletteCanvas');
        const ctx = canvas.getContext('2d');
        // 转盘参数  
        const numSegments = 8; // 奖项数量  
        const anglePerSegment = Math.PI * 2 / numSegments; // 每个奖项的角度  Math.PI=π
        const radius = 150; // 转盘半径  
        const centerX = canvas.width / 2; // 转盘中心X坐标  
        const centerY = canvas.height / 2; // 转盘中心Y坐标  
        const pointerLength = 50; // 指针长度  
        const prizeText = ['奖品1', '奖品2', '奖品3', '奖品4', '奖品5', '奖品6', '奖品7', '奖品8'];
        const prizeColors = ['#ff0000', '#8e44ad', '#0000ff', '#32cd32', '#f0f', '#ff5733', '#90ee90', '#888888']; // 各奖项背景颜色

4、开始旋转转盘

        // 开始旋转转盘  
        function startSpinning() {
            let lastAngle = 0
            if (sessionStorage.getItem('num')) {
                // 使用getItem方法从sessionStorage中获取数据 , 注意要字符串转出num类型
                lastAngle = Number(sessionStorage.getItem('num'));
            }
            let finalAngle = lastAngle;
            let spins = 3; // 转盘旋转的圈数,至少转多少圈
            let duration = 3000; // 旋转总时长(毫秒)  
            let startTime = null;
            let elapsedTime = 0;
            let isSpinning = true;

            let endAngle = Math.floor((Math.random() + spins) * 360); //最终旋转角度
            function animate() {
                if (!isSpinning) return;
                const now = Date.now();//获取当前时间的毫秒数
                if (!startTime) startTime = now;
                elapsedTime = now - startTime;
                let percentage = Math.min(elapsedTime / duration, 1);
                let currentAngle = finalAngle + endAngle * percentage; 
                // 清除画布并绘制转盘和指针  
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                drawRoulette();//绘制转盘背景
                rotateCanvas(currentAngle)//添上转盘旋转动画
                // 如果动画未完成,则继续下一帧  
                if (elapsedTime < duration) {
                    requestAnimationFrame(animate);
                } else {
                    stopSpinning(currentAngle); 停止旋转并显示结果  
                }
            }
            animate();
}

5、转盘旋转动画

function rotateCanvas(angle) {
         var rotateDiv = document.getElementById('rouletteCanvas');
         // 设置元素的旋转角度  
          rotateDiv.style.transform = 'rotate(' + angle + 'deg)';
}

6、停止旋转并显示结果

            // 停止旋转并显示结果  
            function stopSpinning(StopAngle) {
                isSpinning = false;
                let pie_span = 45
                //  存储且存的是字符串类型
                sessionStorage.setItem('num', StopAngle % pie);
                let x = (pie - StopAngle % pie) / pie_span //x=(360-StopAngle%360)/45
                for (let i = 0; i < prizeText.length; i++) {
                    if (x - i >= 0 && x - i < 1) {
                        // 显示获得的奖品  
                        alert(`恭喜您获得了:${prizeText[i]}`);
                    }
                }
            }

7、页面监听卸载

window.addEventListener('beforeunload', function () {
            sessionStorage.clear();
});

四、完整代码

本章为绘制等分等概率转盘,完整代码供学习参考,扩展已详细进行注解。Canvas三重玩法请关注下一章,不容错过呦,快来关注吧!

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>均等分等概率转盘抽奖</title>
    <style>
        .box {
            width: 100%;
            height: 550px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            position: relative;
        }

        canvas {
            display: block;
            margin: 20px auto;
            /* 设置旋转中心点 */
            transform-origin: center center;
        }

        svg {
            position: absolute;
            left: 50%;
            top: 50%;
            width: 70px;
            height: 70px;
            margin-left: -35px;
            margin-top: -65px;
        }
    </style>
</head>

<body>
    <div class="box">
        <canvas id="rouletteCanvas" width="302" height="302"></canvas>
        <svg t="1713059543990" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
            p-id="1835" width="200" height="200">
            <path
                d="M263.577601 776.630449a242.559588 242.559588 0 0 1 138.417007-218.124973L483.818959 23.36268a27.485506 27.485506 0 0 1 54.283873 0l81.824351 535.142796a242.559588 242.559588 0 0 1 138.417006 218.124973 247.369551 247.369551 0 0 1-494.739102 0z"
                p-id="1836" fill="#f4ad13"></path>
        </svg>
        <button onclick="startSpinning()">开始抽奖</button>
    </div>
    <script>
        const canvas = document.getElementById('rouletteCanvas');
        const ctx = canvas.getContext('2d');

        // 转盘参数  
        const numSegments = 8; // 奖项数量  
        const anglePerSegment = Math.PI * 2 / numSegments; // 每个奖项的角度  Math.PI=π
        const radius = 150; // 转盘半径  
        const centerX = canvas.width / 2; // 转盘中心X坐标  
        const centerY = canvas.height / 2; // 转盘中心Y坐标  
        const pointerLength = 50; // 指针长度  
        const prizeText = ['奖品1', '奖品2', '奖品3', '奖品4', '奖品5', '奖品6', '奖品7', '奖品8'];
        const prizeColors = ['#ff0000', '#8e44ad', '#0000ff', '#32cd32', '#f0f', '#ff5733', '#90ee90', '#888888']; // 各奖项背景颜色

        // 绘制转盘背景  
        function drawRoulette() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            for (let i = 0; i < numSegments; i++) {
                const startAngle = (i + 6) * anglePerSegment;
                const endAngle = (i + 7) * anglePerSegment;
                const x = centerX + Math.cos(startAngle) * radius;
                const y = centerY + Math.sin(startAngle) * radius;
                ctx.beginPath();
                ctx.arc(centerX, centerY, radius, startAngle, endAngle, false);  
                ctx.lineTo(centerX, centerY);
                ctx.closePath();
                ctx.fillStyle = prizeColors[i];
                ctx.fill(); 
                ctx.lineWidth = 1;   
                ctx.strokeStyle = '#666'; 
                ctx.stroke();
                const textAngle = startAngle + (endAngle - startAngle) / 2;
                const textX = centerX + Math.cos(textAngle) * (radius - 40);
                const textY = centerY + Math.sin(textAngle) * (radius - 40);
                ctx.save();
                ctx.translate(textX, textY);
                ctx.rotate(textAngle);
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillStyle = '#fff';
                ctx.fillText(prizeText[i], 0, 0);
                ctx.restore();
            }
        }

        // 开始旋转转盘  
        function startSpinning() {
            let lastAngle = 0
            if (sessionStorage.getItem('num')) {
                //  注意要字符串转出num类型
                lastAngle = Number(sessionStorage.getItem('num'));
            }
            let finalAngle = lastAngle;
            let spins = 3; 
            let duration = 3000; 
            let startTime = null;
            let elapsedTime = 0;
            let isSpinning = true;
            let endAngle = Math.floor((Math.random() + spins) * 360);
            function animate() {
                if (!isSpinning) return; 
                const now = Date.now();
                if (!startTime) startTime = now;
                elapsedTime = now - startTime;
                let percentage = Math.min(elapsedTime / duration, 1);  
                let currentAngle = finalAngle + endAngle * percentage;
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                drawRoulette();
                rotateCanvas(currentAngle)
                if (elapsedTime < duration) {
                    requestAnimationFrame(animate);
                } else {
                    stopSpinning(currentAngle);
                }
            }

            function rotateCanvas(angle) {
                var rotateDiv = document.getElementById('rouletteCanvas');
                rotateDiv.style.transform = 'rotate(' + angle + 'deg)';
            }

            // 停止旋转并显示结果  
            function stopSpinning(StopAngle) {
                isSpinning = false;
                let pie = 360
                let pie_span = 45
                sessionStorage.setItem('num', StopAngle % pie);
                let x = (pie - StopAngle % pie) / pie_span
                for (let i = 0; i < prizeText.length; i++) {
                    if (x - i >= 0 && x - i < 1) {
                        alert(`恭喜您获得了:${prizeText[i]}`);
                    }
                }
            }
            animate();
        }
        // 初始化转盘和指针  
        drawRoulette();
        // 页面监听卸载
        window.addEventListener('beforeunload', function () {
            sessionStorage.clear();
        });
    </script>
</body>

</html>

 效果图展示

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炑焽

蓝海新风口,高薪稳定不内卷

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值