uniapp 抽奖跑马灯动画

250 阅读1分钟
<template>
    <view class="lottery px-5" :style="{height:imgHeight * 3+50+'px'}">
        <view class="lottery-box">
            <view class="item" :class="[index==indexSelect?'select':'']" v-for="(item,index) in list" :key="index"
                :style="{
                    height:imgHeight+ 'px',
                    left:item.left,
                    top:item.top
                    }">
                <image lazy-load="true" @tap="toDetailPage({index: index})" class="img" :src="item.img"
                    mode="aspectFit">
                </image>
            </view>
            <view
                :style="{width:imgHeight+'px',height:imgHeight+'px',left : imgHeight + 25.5 + 'px',top : imgHeight + 25 + 'px'}"
                class="lottery-btn flex-center" :class="isRunning?'ative':''" @click="start">开始</view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                list: [{
                    img: "https://cdn.pixabay.com/photo/2017/01/21/13/55/nature-1997282__340.jpg",
                    name: "不要指望他",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/17/12/04/winter-6024017__340.jpg",
                }, {
                    img: "https://cdn.pixabay.com/photo/2021/01/11/21/39/temple-5909803__340.jpg",
                    name: "你在开玩笑么?",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/17/12/04/winter-6024017__340.jpg",
                }, {
                    img: "https://cdn.pixabay.com/photo/2020/01/13/23/15/snowboarding-4763731__340.jpg",
                    name: "可怕",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/17/12/04/winter-6024017__340.jpg",
                }, {

                    img: "https://cdn.pixabay.com/photo/2019/11/30/21/37/stars-4664313__340.jpg",
                    name: "可能",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/13/10/26/snow-6011069__340.jpg",
                }, {
                    img: "https://cdn.pixabay.com/photo/2020/12/23/14/41/forest-5855196_640.jpg",
                    name: "不用担心",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/13/01/29/woman-6010056__340.jpg",
                }, {
                    img: "https://cdn.pixabay.com/photo/2021/01/24/21/52/grand-canyon-5946657__340.jpg",
                    name: "答案就在你身边",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/13/01/29/woman-6010056__340.jpg",
                }, {
                    img: "https://cdn.pixabay.com/photo/2021/01/14/20/32/fish-5917864__340.jpg",
                    name: "大胆一点",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/13/01/29/woman-6010056__340.jpg",
                }, {
                    img: "https://cdn.pixabay.com/photo/2020/01/03/21/32/field-4739176__340.jpg",
                    name: "好运将会降临",
                    img_bg: "https://cdn.pixabay.com/photo/2021/02/13/10/26/snow-6011069__340.jpg",
                }],
                imgHeight: 0,
                stay_index: 0,
                indexSelect: 0,
                isRunning: false
            }
        },
        mounted() {
            this.initImgHeight();
        },
        updated() {
            this.initImgHeight();
        },
        methods: {
            initImgHeight() {
                if (0 === this.imgHeight) {
                    uni.createSelectorQuery()
                        .in(this)
                        .select('.img')
                        .boundingClientRect(data => {
                            if (data) {
                                this.imgHeight = (data.width);
                                this.list = this.list.map((item, index) => {
                                    if (0 === index || 1 === index || 2 === index) {
                                        item.top = "15px"
                                    }
                                    if (0 === index || 6 === index || 7 === index) {
                                        item.left = "15px"
                                    }
                                    if (1 === index || 5 === index) {
                                        item.left = this.imgHeight + 25.5 + 'px'
                                    }
                                    if (3 === index || 7 === index) {
                                        item.top = this.imgHeight + 25 + 'px'
                                    }
                                    if (2 === index || 3 === index || 4 === index) {
                                        item.left = (this.imgHeight * 2) + 35 + 'px'
                                    }
                                    if (4 === index || 5 === index || 6 === index) {
                                        item.top = (this.imgHeight * 2) + 35 + 'px'
                                    }
                                    return item
                                })
                            }
                        })
                        .exec();
                }
            },
            //详情页
            toDetailPage(item) {
                let that = this;
                let list = that.list;
                let index = item.index;
                let data = {
                    curIndex: index,
                    item: list[index],
                    list: list
                };
                this.gotoDetailPage(data);
            },
            //随机数
            random(u) {
                let rnd = Math.random() > 0.5 ? "2" : "1";
                u = u || 3;
                for (var i = 0; i < u; i++) {
                    rnd += Math.floor(Math.random() * 10);
                }
                return Number(rnd);
            },
            //开始
            start() {
                let that = this;
                if (this.isRunning) return
                this.isRunning = true;
                let indexSelect = 0;
                let i = 0;
                let randomNum = this.random(3); // 控制圈数
                //定义停留的位置
                that.stay_index = Math.round(Math.random() * (this.list.length - 1)); //随机数
                let timer = setInterval(() => {
                    ++indexSelect;
                    indexSelect = indexSelect % 8;
                    this.indexSelect = indexSelect;
                    i += 40;
                    // 达到圈数并转到停留位置结束
                    if (i > randomNum && that.stay_index == indexSelect) { 
                        //控制停留位置
                        clearInterval(timer)
                        timer = null;
                        this.msg_modal("抽中了" + that.list[indexSelect].name, '恭喜您')
                        this.isRunning = false

                    }
                }, (80 + i)) // 控制转速
            },
            gotoDetailPage(e) {
                let list = e.list;
                let idx = e.curIndex;
                let list_img = [];
                let item = e.item;

                list.forEach(item => {
                    list_img.push(item.img)
                })
                if (list_img && list_img.length > 0) {
                    uni.previewImage({
                        current: list_img[idx], //  传 Number H5端出现不兼容
                        urls: list_img,
                        indicator: "number",
                        loop: true,
                    });
                }
            },
            msg_modal(content, title = '温馨提示') {
                let that = this;

                //统一提示方便全局修改
                if (Boolean(content) === false) {
                    return;
                }
                uni.showModal({
                    title: title,
                    content: content,
                    confirmText: '确定',
                    showCancel: false,
                    confirmColor: '#33CCCC',
                    success(res) {
                        if (res.confirm) {
                            that.stay_index = 0;
                            that.indexSelect = 0
                        }
                    }
                })
            }
        }
    }
</script>
<style lang="scss">
    .lottery {
        width: 100%;
        margin: 40rpx auto;
        border-radius: 40rpx;
        box-sizing: border-box;

        &-box {
            width: 100%;
            position: relative;
            height: 100%;
            border-radius: 40rpx;
            background-color: pink;

            .item {
                position: absolute;
                width: calc((100% - 45px) / 3);
                background-color: #fff;
                border-radius: 15rpx;

                .img {
                    position: absolute;
                    margin: auto;
                    top: 0;
                    left: 0;
                    bottom: 0;
                    right: 0;
                    width: 100%;
                }

            }

            .select {
                background-color: palegoldenrod !important;
            }
        }

        &-btn {
            position: absolute;
            border-radius: 15rpx;
            background-color: purple;
            color: #fff;
            font-size: 32rpx;
            font-weight: bold;
            line-height: 1;

        }

        .ative {
            opacity: 0.6 !important;
        }
    }
</style>

效果图如下:

image.png

参考链接:ext.dcloud.net.cn/plugin?id=4…