css实现北斗七星动效

208 阅读3分钟
<template>
    <view class="group"
        :style="{height:imgHeight,'background':'url(背景星星图片) left top/100% no-repeat'}">
        <image class="line" :src="逐个变亮路线" mode="widthFix"
            v-if="7>groups.length"></image>
        <image class="line" :src="全亮路线" mode="widthFix" v-else>
        </image>
        <view class="schedule">
            进度 {{percent}}%
        </view>
        <view class="users">
            <view class="item flex-align" :style="{left:positions[index].left,top:positions[index].top}"
                v-for="(item,index) in 7" :key="'key'+index">
                <image class="logo" :style="{width:positions[index].size+'rpx',height:positions[index].size+'rpx'}"
                    :src="问号图片">
                </image>
            </view>
            <view class="item user flex-align" :class="'gif'+index"
                :style="{left:positions[index].left,top:positions[index].top}" v-for="(item,index) in groups"
                :key="index">
                <view>
                    <image class="logo"
                        :style="{width:positions[index].size+'rpx',height:positions[index].size+'rpx'}"
                        :src="用户头像">
                    </image>
                </view>
                <view class="money font-size-left-10" :class="positions[index].classname"
                    v-if="item.balance && 0!==index">
                    +{{金额}}元
                </view>
                <image class="right-tail" :src="右边尾巴图片"
                    mode="heightFix" v-if="0!==index && 2!==index">
                </image>
                <image class="left-tail" :src="左边尾巴图片"
                    mode="heightFix" v-if="0!==index && 2===index">
                </image>
                <image :style="{width:(positions[index].size+30)+'rpx',height:(positions[index].size+30)+'rpx'}"
                    class="light" :src="光圈" mode="scaleToFill"
                    v-if="0!==index">
                </image>
            </view>
        </view>
        <view class="barrages" v-if="isSuccess">
            <view class="success">
                <image class="gif" :src="成功背景图" mode="scaleToFill">
                </image>
                <view class="barrages-item">
                    <view class="tag flex-center">
                        组团成功:成团奖金
                        <text class="color-base-text">+</text>
                        <text class="color-base-text">{{总奖金}}元</text>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    const POSITION = {
        0: {
            top: '67%',
            left: '38%',
            size: 124,
            classname: ''
        },
        1: {
            top: '67%',
            left: '70%',
            size: 64,
            classname: 'right-radius'
        },
        2: {
            top: '51%',
            left: '34%',
            size: 86,
            classname: 'right-radius'
        },
        3: {
            top: '45%',
            left: '49%',
            size: 78,
            classname: 'right-radius'
        },
        4: {
            top: '37%',
            left: '50%',
            size: 66,
            classname: 'left-radius'
        },
        5: {
            top: '31%',
            left: '51%',
            size: 54,
            classname: 'left-radius'
        },
        6: {
            top: '26%',
            left: '43%',
            size: 54,
            classname: 'left-radius'
        }
    }
    export default {
        props: ['infos', 'memberInfo', 'totalPrize'],
        watch: {
            totalPrize() {
                setTimeout(() => {
                    // 展示组团成功动效
                    this.isSuccess = true
                }, 500)
                setTimeout(() => {
                    // 成功跳转
                }, 2800)
            }
        },
        data() {
            return {
                positions: POSITION,
                groups: [],
                index: 0,
                percent: 0,
                info: {},
                imgHeight: '',
                join: false,
                isSuccess: false
            }
        },
        mounted() {
            // 获取背景图高度,根据背景图高度定位
            this.imgHeight = this.initHeight(1.78, 'adaption') + 'px';
        },
        methods: {
            initHeight(heightRatio, type) {
                let info = uni.getSystemInfoSync();
                // 返回当前页面高度
                if ('height' === type) {
                    return info.windowHeight
                }
                // 宽屏自适应超过768px比例缩放
                if ('adaption' === type && info.windowWidth >= 768) {
                    return 768 * heightRatio;
                }
                // 根据比例返回高度
                return info.windowWidth * heightRatio;
            },
            init() {
                this.groups = []
                // 自己头像
                this.groups.push({
                    head_img: this.memberInfo.head_img ? this.$util.img(this.memberInfo.head_img) : this.$util
                        .getDefaultImage().head
                })
                this.initGroups()
            },
            initGroups() {
                this.index = 0
                let times = setInterval(() => {
                    let item = this.infos.list[this.index]
                    // 将用户展示出来
                    this.groups.push(item)
                    this.index++
                    // 进度
                    this.percent = 6 === this.index ? 100 : (Math.floor(100 / 6 * 100) / 100 * this.index)
                        .toFixed(2)
                    this.info = item
                    if (this.index > this.infos.list.length - 1) {
                        if (this.infos.list.length >= 6) {
                            // 组团成功
                        }
                        clearInterval(times)
                        return
                    }
                }, 900)
            }
        }
    }
</script>

<style lang="scss" scoped>
    .group {
        width: 100%;
        height: 100vh;
        position: relative;
        overflow: auto;

        .line {
            width: 100%;
        }

        .barrage {
            width: 100%;
            position: absolute;
            top: 5%;
        }

        .img {
            width: 70%;
            position: absolute;
            top: 16%;
            left: 15%;
        }

        .schedule {
            color: #FF4169;
            font-weight: bold;
            position: absolute;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
        }

        .users {
            .item {
                position: absolute;

                image {
                    border-radius: 50%;
                }

                .desc {
                    color: #fff;
                    margin-left: 20rpx;
                }

                .money {
                    color: #fff;
                    background-color: #FF4169;
                    padding: 5rpx 20rpx;
                    opacity: 0;
                }

                .right-radius {
                    border-radius: 20rpx 20rpx 20rpx 0;
                }

                .left-radius {
                    border-radius: 20rpx 20rpx 0 20rpx;
                }
            }

            .user {
                .logo {
                    border: 1px solid #fff;
                    box-shadow: 0 0 12rpx 5rpx #ffe09d;
                }

                .light {
                    opacity: 1;
                    position: absolute;
                    left: -15rpx;
                    top: -15rpx;
                }
            }

            .right-tail {
                height: 60px;
                position: absolute;
                left: -30%;
                animation: lightOpacity 0.3s linear forwards;
            }

            .left-tail {
                height: 60px;
                position: absolute;
                left: -120%;
                animation: lightOpacity 0.3s linear forwards;
            }

            @keyframes moneyScale {
                0% {
                    opacity: 0;
                    transform: scale(1);
                }

                50% {
                    opacity: 1;
                    transform: scale(0.1);
                }

                100% {
                    opacity: 1;
                    transform: scale(1);
                }
            }

            .gif1,
            .gif2,
            .gif3 {
                .money {
                    position: relative;
                    left: 20rpx;
                    animation: moneyScale 0.5s linear forwards 0.3s;
                }
            }

            @keyframes lightOpacity {
                0% {
                    opacity: 1;
                }

                100% {
                    opacity: 0;
                }
            }

            .gif1,
            .gif2,
            .gif3,
            .gif4,
            .gif5,
            .gif6 {
                .light {
                    animation: lightOpacity 0.5s linear forwards 0.5s;
                }
            }

            .gif4,
            .gif5,
            .gif6 {
                .money {
                    position: relative;
                    left: -110%;
                    animation: moneyScale 0.5s linear forwards 0.3s;
                }
            }

            .gif1 {
                animation: flyIn1 0.15s ease-in forwards;

                @keyframes flyIn1 {
                    0% {
                        left: 100%;
                    }

                    100% {
                        left: 70%;
                    }
                }

            }

            .gif2 {
                animation: flyIn2 0.15s ease-in forwards;

                @keyframes flyIn2 {
                    0% {
                        left: 0%;
                    }

                    100% {
                        left: 34%;
                    }
                }
            }

            .gif3 {
                animation: flyIn3 0.15s ease-in forwards;

                @keyframes flyIn3 {
                    0% {
                        left: 100%;
                    }

                    100% {
                        left: 49%;
                    }
                }
            }

            .gif4 {
                animation: flyIn4 0.15s ease-in forwards;

                @keyframes flyIn4 {
                    0% {
                        left: 100%;
                    }

                    100% {
                        left: 50%;
                    }
                }
            }

            .gif5 {
                animation: flyIn5 0.15s ease-in forwards;

                @keyframes flyIn5 {
                    0% {
                        left: 100%;
                    }

                    100% {
                        left: 51%;
                    }
                }
            }

            .gif6 {
                animation: flyIn6 0.15s ease-in forwards;

                @keyframes flyIn6 {
                    0% {
                        left: 100%;
                    }

                    100% {
                        left: 43%;
                    }
                }
            }
        }
    }

    .barrages {
        width: 100%;
        height: 320rpx;
        overflow: hidden;
        white-space: nowrap;
        position: fixed;
        top: 50%;
        transform: translateY(-50%);

        .success {
            width: 100%;
            height: 100%;
            position: relative;
            animation: appear 0.5s linear forwards, disappear 0.5s linear forwards 1.5s;

            .gif {
                width: 100%;
                height: 100%;
                position: absolute;
                left: 0%;
                top: 0;
            }

            @keyframes appear {
                0% {
                    opacity: 0;
                    transform: translateX(100%);
                }

                100% {
                    opacity: 1;
                    transform: translateX(0);
                }
            }

            @keyframes disappear {
                0% {
                    opacity: 1;
                    transform: translateX(0);
                }

                100% {
                    opacity: 0;
                    transform: translateX(-100%);
                }
            }

            .tag {
                position: relative;
                height: 320rpx;
                color: #fff;
                font-size: 30rpx;

                text {
                    font-weight: bold;
                    font-size: 44rpx;
                }
            }
        }
    }
</style>

效果如下: pan.baidu.com/s/1-Ur5V2xF…