H5 抽奖页面

好久之前就想去写一个这样的示例了,然后就忘了…

效果

在线链接

https://linyisonger.github.io/H5.Examples/?name=./34.%E6%8A%BD%E5%A5%96%E9%A1%B5%E9%9D%A2.html

图片可能会丢失,都是在网上随便搜的。

逻辑

这里使用到了贝塞尔函数,如果不懂可以看看。

三钻老师的 https://blog.csdn.net/TriDiamond6/article/details/115438950

这种数学对于我来说太难了,看不是很懂。

首先先引用@3r/tool这个包

⚠生产可不要这样去写哦!这种写法可能会导致一些适配问题,我这里是演示,就很随便。

<script type="module">
import { Maths, Randoms, Animation } from "https://gcore.jsdelivr.net/npm/@3r/[email protected]/index.js"
script>

书写元素位置,这个位置顺序影响着效果中黄框转动的方向,当然你可以使用javascript去循环出来,我比较赖,哈哈哈哈。

<div class="prize-container">
    <div class="prize-item" style="left: 0;top: 0;">div>
    <div class="prize-item" style="left: 200px;top: 0;">div>
    <div class="prize-item" style="left: 400px;top: 0;">div>
    <div class="prize-item" style="left: 400px;top: 200px;">div>
    <div class="prize-item" style="left: 400px;top: 400px;">div>
    <div class="prize-item" style="left: 200px;top: 400px;">div>
    <div class="prize-item" style="left: 0;top: 400px;">div>
    <div class="prize-item" style="left: 0;top: 200px;">div>
    <div class="prize-turn" style="left: 200px;top: 200px;">开始转动div>
div>

将奖品渲染到页面盒子中去

let prizes = [
    {
        name: '苹果13',
        weight: 1,
        imgSrc: 'https://img10.360buyimg.com/n1/s450x450_jfs/t1/122791/34/35195/31712/63e4d4f8Fc242eca8/e8b37a3c1c707551.jpg'
    },
    {
        name: '兰博基尼5元优惠券',
        weight: 1000,
        imgSrc: 'https://youjia-image.cdn.bcebos.com/modelImage/5567ba4dd1ac4a059511ce1968cf8e31/16233074995453266694.jpg@!watermark_1'
    },
    {
        name: '香港一日游满5000-5券',
        weight: 200,
        imgSrc: 'https://wx4.sinaimg.cn/mw690/0076qYpPgy1hb22ws8hjdj30nw0fydp9.jpg'
    },
    {
        name: '王者荣耀绝美皮肤一套',
        weight: 200,
        imgSrc: 'https://img2.40407.com/upload/202111/09/091448320eecb8dV5D4vrsertjn.jpg'
    },
    {
        name: '鼠标垫',
        weight: 200,
        imgSrc: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcbu01.alicdn.com%2Fimg%2Fibank%2F2020%2F940%2F595%2F17542595049_1110060834.jpg&refer=http%3A%2F%2Fcbu01.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1678946052&t=f6b6664f8bfb36eee1bfa142f74e6dc5'
    },
    {
        name: '再来一次',
        weight: 100,
        imgSrc: 'https://q.qqbiaoqing.com/q/2017/03/04/33a5791469c29d97fea7e7a96debdf4c.gif'
    },
    {
        name: '吹风机',
        weight: 20,
        imgSrc: 'https://img2.baidu.com/it/u=4244035486,2082281147&fm=253&fmt=auto&app=138&f=JPEG?w=777&h=500'
    },
    {
        name: '扫地机器人',
        weight: 10,
        imgSrc: 'https://img0.baidu.com/it/u=305646170,4023681037&fm=253&fmt=auto&app=120&f=JPEG?w=600&h=433'
    },
]

// 展示效果
for (let i = 0; i < prizeDomList.length; i++) {
    const prizeItem = prizeDomList[i];
    const prizeText = document.createElement('div')
    const prizeImage = document.createElement('img')


    prizeText.textContent = prizes[i].name
    prizeImage.setAttribute("src", prizes[i].imgSrc)

    prizeItem.appendChild(prizeImage)
    prizeItem.appendChild(prizeText)
}

这里通过awaitsetTimeout进行等待,通过循环次数的easeIn的值延迟时间的比例来更改延迟时间*,从而达到从快到慢的过程。

通过奖品权重值的大小来随机出现占比程度,越大越容易出现。

曲线值大于0.9开始索引取余于数组长度是否与结束索引相等的时候,判断是否可以结束。

关于曲线值大于0.9这点儿写的感觉有点随便了,一般写应该是从开始就算好到哪里停的,这点儿我不知道怎么去算,会的可以跟我讲讲,谢谢~

// 等待时间
let waitTime = function (time) {
    return {
        then: function (resolve) {
            setTimeout(resolve, time)
        }
    }
}
// 转动
let turn = async function () {
    let offset = 1 / (prizes.length * 10) // 执行次数
    let interval = 200; // 延迟
    let minInterval = 50; // 最小延迟
    let endIndex = Randoms.getRandomIndexByWeight(prizes) // 随机结束奖品
    let lastDom = null
    for (let i = 0; i <= 1; i += offset) {
        // 延迟时间
        await waitTime(Math.max(Animation.easeIn(i) * interval, minInterval))
        lastDom?.classList?.remove('active');
        lastDom = prizeDomList.item(startIndex % prizeDomList.length)
        lastDom.classList.add('active')
        if (i > .9 && (startIndex % prizeDomList.length === endIndex)) break;
        startIndex++;
    }
    let name = prizes[endIndex].name

    setTimeout(() => {
        if (name == "再来一次")
            alert(`${name}吧~`)
        else
            alert(`您获得了${name}`)
    }, interval);
}

源码

https://github.com/linyisonger/H5.Examples

你可能感兴趣的:(H5,前端,javascript)