抽奖轮盘(面试机会)

意义轮盘(哈哈哈)

可以自由配置中奖比例

<!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>
        * {
            margin: 0;
            padding: 0;
        }

        #win_wheel {
            display: flex;
        }

        .wheel {
            display: flex;
            justify-content: center;
            align-items: center;

            width: 50%;
            height: 40rem;
            background-color: orange;
        }

        .list {
            flex: 1;
            background-color: #ff0;
            padding: 4rem;
        }

        .in {
            position: absolute;

            z-index: 2;
            width: 8rem;
            height: 8rem;
            border-radius: 50%;
            background-color: yellow;

            line-height: 8rem;
            text-align: center;
        }

        .in::after {
            position: absolute;
            top: -2rem;
            left: 3rem;
            content: "";
            width: 0;
            height: 0;
            border: 1rem solid;
            border-color: transparent transparent rgb(252, 249, 249) transparent;
        }

        .in:hover {
            cursor: pointer;
        }


        .circle {
            position: relative;
            overflow: hidden;
            margin: auto;
            width: 30rem;
            height: 30rem;
            border-radius: 50%;
            background-color: skyblue;

            transition: all 5s ease;
        }

        .togather {
            position: absolute;
            right: 50%;
            bottom: 50%;
            width: 1000rem;
            height: 1000rem;
            transform-origin: right bottom;
            border-width: 0rem;
        }

        .halfCircle {
            position: absolute;
            bottom: 50%;
            right: 50%;
            width: 1000rem;
            height: 1000rem;
            transform-origin: bottom center;
        }

        .name {
            position: absolute;
            z-index: 1;
            width: 5rem;
            height: 15rem;
            line-height: 10rem;
            left: 50%;
            font-size: 1.5rem;
            transform-origin: bottom center;
            transform: translateX(-2.5rem);
            text-align: center;
        }
    </style>
</head>

<body>
    <div id="win_wheel">
        <div class="wheel">
            <div class="circle">
                <!-- 动态插入 -->
            </div>
            <div class="in">
                <h1>抽奖</h1>
            </div>
        </div>
        <div class="list">
            <table id='table_id'>
                <th>奖项</th>
                <th>中奖率</th>
                <th>操作</th>
                <!-- 动态插入 -->
                <tr id="ta_tr">
                    <td><input id="val1" type="text" placeholder="请输入奖项"></td>
                    <td><input id="val2" type="text" placeholder="设定中奖率"></td>
                    <td><button class="addBtn" data-name="add">添加</button></td>
                </tr>
            </table>
        </div>
    </div>

    <script>
        const tableEl = document.getElementById('table_id')
        const trEl = document.querySelector('#ta_tr')
        const v1El = document.querySelector('#val1')
        const v2El = document.querySelector('#val2')
        const circleEl = document.querySelector('.circle')
        const inEl = document.querySelector('.in')

        let id = 1
        let list = []
        let item = {}
        let isHas = false
        let gasdeg = 0

        // 生成随机颜色
        function Color() {
            this.r = Math.floor(Math.random() * 255);
            this.g = Math.floor(Math.random() * 255);
            this.b = Math.floor(Math.random() * 255);
            this.color = 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',1)';
        }

        // 给页面添加元素
        function changeHtml() {
            const item = list[list.length - 1]
            const tr = document.createElement('tr')
            tr.innerHTML = `
                    <td><input type="text" value="${item.val1}" placeholder="请输入奖项" data-id="${item.id}"></td>
                    <td><input type="text" value="${item.val2}" placeholder="设定中奖率" data-id="${item.id}"></td>
                    <td><button data-name="delete" data-id="${item.id}">删除</button></td>
                `
            trEl.insertAdjacentElement('beforebegin', tr)
        }

        // 获取角度
        function handlePieData() {
            let currentRotate = 0
            let preRdeg = 0

            // 获取所有奖项的概率总和
            let sum = list.reduce((pre, item) => {
                return pre + (item.val2 - 0)
            }, 0)

            list.map((item, index) => {
                const dEl = document.createElement('div')
                // 每个奖项对应的圆心角度数
                let rdeg = Math.ceil((item.val2 - 0) / sum * 360)

                if (index !== 0) {
                    currentRotate = currentRotate + preRdeg
                    preRdeg = rdeg
                } else {
                    currentRotate = 0
                    preRdeg = rdeg
                }

                // 保存到item中
                item.rdeg = rdeg  // 每个奖项占据的角度
                item.rotate = currentRotate  // rotate(currentDeg)
            })
        }

        // 存储数据
        function addItem() {
            isHas = false
            list.forEach(iten => {
                if (iten.val1 === item.val1) {
                    // 已经有相同奖项
                    isHas = true
                }
            })

            // 奖项相同不添加
            if (!isHas && item.id) {
                // 插入数据
                list.push(item)
                handlePieData()

                // 更新页面
                changeHtml()
                addPie()

                // 重置数据
                item = {}
                v1El.value = null
                v2El.value = null
            } else {
                alert('奖项相同或输入奖项不完整')
            }

        }

        // 将扇形添加到圆中
        function addPie() {
            circleEl.innerHTML = ""
            list.forEach(item => {
                const div = document.createElement('div')
                const nameDiv = document.createElement('div')
                const divStyle = div.style
                let rdeg = item.rdeg
                let rotate = item.rotate + 90
                let nameRot = rotate + rdeg / 2 - 90

                div.className = 'togather'
                divStyle.backgroundColor = item.color
                nameDiv.innerText = item.val1
                nameDiv.className = "name"
                circleEl.appendChild(nameDiv)

                switch (true) {
                    case rdeg === 360:
                        div.className = "circle"
                        circleEl.appendChild(div)
                        console.log('360触发', rotate, item.color)
                        break
                    case rdeg > 180:
                        // 将半个圆添加
                        const divOverb = document.createElement('div')
                        divOverb.style.backgroundColor = item.color
                        divOverb.style.transform = `translate(15rem, 0rem) rotate(${rotate}deg)`
                        divOverb.className = 'halfCircle'
                        circleEl.appendChild(divOverb)

                        nameDiv.style.transform = `translateX(-2.5rem) rotate(${nameRot}deg)`
                        console.log('大于180触发0', rdeg, rotate, item.color)


                        rdeg = rdeg - 180
                        rotate = rotate + 180
                        if (rdeg - 180 > 90) {
                            // 添加四分之一个圆
                            const divOverbb = document.createElement('div')
                            divOverbb.style.transform = `rotate(${rotate}deg) skewX(0deg)`
                            divOverbb.style.backgroundColor = item.color
                            divOverbb.className = 'togather'
                            circleEl.appendChild(divOverbb)

                            rdeg = rdeg - 90
                            rotate = rotate + 90
                            console.log('大于180触发2', rdeg, rotate)
                        }

                        // 剩余部分一定小于90
                        divStyle.transform = `rotate(${rotate}deg) skewX(${90 - rdeg}deg)`
                        divStyle.backgroundColor = item.color
                        console.log('大于180触发3', rdeg, rotate, item.color)
                        break
                    case rdeg === 180:
                        const divOvera = document.createElement('div')
                        divOvera.style.transform = `translate(15rem, 0rem) rotate(${rotate}deg)`
                        divOvera.style.backgroundColor = item.color
                        divOvera.className = 'halfCircle'
                        circleEl.appendChild(divOvera)

                        nameDiv.style.transform = `translateX(-2.5rem) rotate(${nameRot}deg)`
                        console.log('180触发', rdeg, rotate, item.color)
                        break
                    case rdeg > 90:
                        divStyle.transform = `rotate(${rotate}deg) skewX(${90 - rdeg}deg)`
                        circleEl.appendChild(div)

                        nameDiv.style.transform = `translateX(-2.5rem) rotate(${nameRot}deg)`
                        console.log('大于90触发', rdeg, rotate)
                        break
                    case rdeg === 90:
                        divStyle.transform = `rotate(${rotate}deg) skewX(0deg)`
                        circleEl.appendChild(div)
                        nameDiv.style.transform = `translateX(-2.5rem) rotate(${nameRot}deg)`
                        console.log('90触发', rdeg, rotate, nameRot)
                        break
                    case rdeg < 90:
                        divStyle.transform = `rotate(${rotate}deg) skewX(${90 - rdeg}deg)`
                        circleEl.appendChild(div)
                        nameDiv.style.transform = `translateX(-2.5rem) rotate(${nameRot}deg)`
                        console.log('小于90触发', rdeg, rotate, nameRot)
                        break
                }
            })
        }

        // 移除奖项
        function removeItem(e) {
            const removeNode = e.target.parentNode.parentNode
            // 删除数据
            list = list.filter(iten => {
                // 转成数字后比较
                return iten.id !== e.target.dataset.id - 0
            })
            // 删除dom元素
            tableEl.appendChild(removeNode)
            tableEl.removeChild(removeNode)

            // 重新计算比例
            handlePieData()
            // 更新饼图
            addPie()
        }

        // 计算抽中的奖项
        function getEnd(rdeg) {
            // 每个奖项概率累加之和
            let sumDeg = 0
            // 旋转随机度数取360的余数
            let gasdeg = rdeg % 360
            // 保存中奖名字
            let name = ''

            for (let i = 0; i < list.length; i++) {
                sumDeg += list[i].rdeg
                console.log(gasdeg, sumDeg)
                if (i === 0 && sumDeg > gasdeg) {
                    name = list[0].val1
                    break
                } else if (sumDeg > gasdeg) {
                    name = list[i].val1
                    break
                }
            }

            return `恭喜您荣获:${name}`
        }

        // 监听添加事件
        tableEl.addEventListener('click', (e) => {
            if (e.target.dataset.name === 'add') {
                addItem(e)
            }
            if (e.target.dataset.name === 'delete') {
                // 删除奖项
                removeItem(e)
            }
        })

        // 初始化item数据
        tableEl.addEventListener('change', (e) => {
            if (e.target.id === 'val1') {
                item.val1 = e.target.value
            } else if (e.target.id === 'val2') {
                item.val2 = e.target.value
            }

            // 初始化id
            if (item.val1 && item.val2) {
                id++
                item.id = id
            }

            // 初始化颜色
            if (!item.color) {
                item.color = new Color().color
            }
        })

        // 监听抽奖事件
        inEl.addEventListener('click', () => {
            // 生成随机数
            const anyCount = Math.random() * 50 + 20
            const anyRo = Math.random() * 360 + 360
            gasdeg += anyCount * anyRo

            // 20只是回旋效果,不参与旋转角度运算
            circleEl.style.transform = `rotate(-${gasdeg + 20}deg)`
            let timer1 = setTimeout(() => {
                circleEl.style.transform = `rotate(-${gasdeg}deg)`
                let timer2 = setTimeout(() => {
                    alert(getEnd(gasdeg))
                }, 1000)
            }, 5000)
        })
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值