html+css+JavaScript 实现 转盘

web作业

首先通过 HTML 建立结构,然后用 CSS 设计样式,最后通过 JavaScript 实现交互
逻辑。采用 Canvas 绘图技术来动态渲染转盘,并利用面向对象的编程方法来组织
和管理游戏逻辑,实现了以下功能:
  1. 每次重新生成随机个随机奖项(固定一个谢谢参与)
  2. 顺\逆时针旋转
  3. 加速\减速
  4. 暂停
  5. 弹窗显示结果

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Spin Wheel</title>
    <link href="wheel.css" rel="stylesheet">
</head>
<body>
    <div id="wheel">
        <div id="container">
            <canvas id="wheelCanvas"></canvas>
        </div>      
        <div id="pointer"></div>
        <div id="pot"></div>
    </div>

    <div id="BUTTON">
        <button id="againButton">again</button>
        <button id="startButton">开始</button>
        <button id="stopButton">暂停</button>
        <button id="accelerateButton">+</button>
        <button id="lowerButton">-</button>
        <button id="anticlockwiseButton">逆时针</button>
    </div>

    <script src="wheel.js"></script>
</body>
</html>
body {
    margin: 0 ;
    overflow: auto;
    display: grid;
    place-items: center;
    min-height: 100vh;
    position: relative;

    background-attachment: fixed;
    background-size: cover;
    background-position: center;
    background-color:azure;
}

#wheel{
    width:550px;
    height: 550px;
    border-radius: 50%;
    background-color:aquamarine;
    margin: 20px auto;
    position: relative;
    overflow: hidden;
    z-index: 1;
}
#container{
    width:550px;
    height: 550px;
}
#wheelCanvas{
    width: 550px;
    height: 550px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    z-index: 2;
}

#pointer {
    position: absolute;
    left: 50%; 
    top: 50%; 
    width: 0; 
    height: 0; 
    border-left: 9px solid transparent; 
    border-right: 9px solid transparent; 
    border-bottom: 110px solid gold;
    transform: translate(-50%, -100%); 
    z-index: 3;
}
#pot{
    position: absolute;
    left: 50%; 
    top: 50%; 
    border-radius: 50%;
    width: 85px; 
    height: 85px; 
    color: gold;
    background-color: gold;
    transform: translate(-50%, -50%);
    z-index: 3;
}

#BUTTON{
    display: flex;
    justify-content: space-between;
    align-items: center;
}
button{
    margin: 10px;
    padding: 10px 20px;
    border-radius: 20%;
    background-color:lavenderblush;
    border-color: lightblue;
}
//基础奖项数组
const basePrizes = [
    '奖品1', '奖品2', '奖品3', '奖品4', '奖品5',
    '奖品6', '奖品7', '奖品8', '奖品9', '奖品10',
    '奖品11', '奖品12', '奖品13', '奖品14', '奖品15',
    '奖品16', '奖品17', '奖品18', '奖品19', '奖品20'
];
//颜色数组
const colors = [
    '#9fa8da', // 莫兰蒂淡紫
    '#90caf9', // 莫兰蒂天蓝
    '#a5d6a7', // 莫兰蒂淡绿
    '#ffe082', // 莫兰蒂淡黄
    '#b0bec5'  // 莫兰蒂淡灰
];

const canvas = document.getElementById("wheelCanvas");
const ctx = canvas.getContext("2d");

class SpinWheel {
    constructor() {
        this.prizes = []; // 存储奖项
        this.isSpinning = false;
        this.isStop = false;

        this.rot = 0;
        this.add = 0;
        this.time = null;

        this.setupCanvas(); 
        this.drawWheel(); 

        this.startButton = document.getElementById("startButton");
        this.stopButton = document.getElementById("stopButton");
        this.accelerateButton = document.getElementById("accelerateButton");
        this.anticlockwiseButton = document.getElementById("anticlockwiseButton");
        this.againButton = document.getElementById("againButton");
        this.lowerButton = document.getElementById("lowerButton");

        // 设置按钮点击事件处理
        this.againButton.addEventListener("click",()=>{
            this.rot=0;
            this.add=3;
            this.setupCanvas(); 
            this.drawWheel();  
        });
    
        this.startButton.addEventListener("click", () => {
            if(this.add <= 0){
                this.add = 3;
            }
            clearInterval(this.time);
            // console.log(this.prizes);

            if(!this.isSpinning){
                this.time = setInterval(() => {
                    this.animateSpin();
                }, 10); // 利用定时器开始旋转 
            }else{
                return;
            }
            
            if (this.isStop && !this.isSpinning){
                this.isStop = false;
                this.isSpinning=true;
            }
        });

        this.stopButton.addEventListener("click", () => {
            clearInterval(this.time); 
            this.isSpinning = false; 
            this.isStop = true;
            this.stopSpin();
        });

        this.anticlockwiseButton.addEventListener("click", () => {
            if(this.add <= 0){
                this.add = 3;
            }
            clearInterval(this.time);
            if(!this.isSpinning){
                this.time = setInterval(() => {
                    this.toggleDirection();
                }, 10); // 利用定时器开始旋转 
            }else{
                return;
            }
            
            if (this.isStop && !this.isSpinning){
                this.isStop = false;
                this.isSpinning=true;
            }
        });

        this.accelerateButton.addEventListener("click", () => {
            if (this.add<15){
                this.add+=2;
            }
        });
        this.lowerButton.addEventListener("click",() => {
            if (this.add>=2){
                this.add-=2;

            }
        });
    }

    setupCanvas() {
        // 设置 Canvas 大小
        canvas.width = 400;
        canvas.height = 400;
        // 设置原点在 Canvas 中心
        ctx.translate(canvas.width / 2, canvas.height / 2);
    }

    drawWheel() {
        const prizeNum = Math.floor(Math.random() * 6) + 5; // 随机设置奖项数量
        const anglePerPrize = (2 * Math.PI) / prizeNum; // 角度
        const radius = 160; 
        this.prizes=[];
    
        for (let i = 0; i < prizeNum; i++) {
            const startAngle = i * anglePerPrize;
            const endAngle = (i + 1) * anglePerPrize;
            
    
            // 随机选择奖项和颜色
            const prizeIndex = Math.floor(Math.random() * basePrizes.length);
            let prize = basePrizes[prizeIndex];           
            var color = colors[i % colors.length];

            //避免第一个和最后一个颜色相同
            //谢谢参与
            if(i==prizeNum-1 ){
                if(prizeNum%colors.length == 1){
                    color = colors[(i + 1) % colors.length];
                }               
                prize = "谢谢参与!";
            }
            this.prizes[i] = prize;

            // 计算文字位置
            const textAngle = (startAngle + endAngle) / 2;
            const textRadius = radius * 0.8; // 更新文字半径
            const x = Math.cos(textAngle) * textRadius;
            const y = Math.sin(textAngle) * textRadius;
    
            // 绘制扇形
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.arc(0, 0, radius, startAngle, endAngle);
            ctx.fillStyle = color;
            ctx.fill();
            ctx.closePath();
    
            // 文字
            ctx.save(); 
            ctx.translate(x, y);
            ctx.rotate(textAngle + Math.PI / 2); 
            ctx.fillStyle = "white"; 
            ctx.font = "20px Arial"; 
            ctx.fillText(prize, -ctx.measureText(prize).width / 2, 13); 
            ctx.restore(); 
        }
    }
    
    //旋转
    animateSpin() {
        const container = document.getElementById("container");
        this.rot += this.add;
        container.style.transform = "rotate(" + this.rot + "deg)";

    }
    //逆时针旋转
    toggleDirection(){
        const container = document.getElementById("container");
        this.rot -= this.add;
        container.style.transform = "rotate(" + this.rot + "deg)";
    }
    
    stopSpin() {
        const prizeNum = this.prizes.length;

        // 每个扇形角度
        const anglePerPrize = 360 / prizeNum;

        // 计算停止时的角度
        const stopAngle = (this.rot+90) % 360;
        
        // 确定奖项
        let winningIndex = Math.floor(stopAngle / anglePerPrize);
        //处理逆时针造成的角度为负的情况
        while(winningIndex<0){
            winningIndex += prizeNum;
        }
        //从最后一个倒着数
        winningIndex = this.prizes.length-1-winningIndex;

        setTimeout(() => {
            this.showPrize(winningIndex);
        }, 200); // 
        // console.log(winningIndex);
    }
     
    showPrize(winningIndex) {
        const winningPrize = this.prizes[winningIndex];
        // console.log(winningPrize);

        //输出结果
        if(winningIndex == this.prizes.length-1){
            alert(`谢谢参与!`);
        }else{
            alert(`恭喜你获得了 ${winningPrize}!`);
        }
        
    }  
}

window.onload = function() {
    const container = document.getElementById("container");
    const game = new SpinWheel();
};

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值