css引导弹窗动效

81 阅读1分钟
<template>
    <view>
        <view class="faq" :class="0===meScrollY && !hideFaq ?'faqAppear':( hideFaq?'hideFaq':'faqDisappear') ">
            <view class="content flex-column-center" @click="showQuestion=!showQuestion">
                <image :class="{'rotate':rotate}" :src="头像"
                    mode="widthFix"></image>
                <image :src="怎么玩图片" mode="widthFix"></image>
            </view>
            <view class="questions" :class="{'hideQuestions':hideFaq}" v-if="showQuestion">
                <view v-for="(item,index) in questions" :key="index" @click="openPopup(item)">{{item.title}}</view>
            </view>
        </view>
        <view class="rule-popup">
            <uni-popup ref="popup">
                <view class="rule-popup-content" :class="{'hide-popup':isClose}"
                    :style="{background:'url(图片) left top/100% 100% no-repeat'}">
                    <uni-icons class="close" type="closeempty" color="#fff" size="30" @click="closePopup"></uni-icons>
                    <view class="title flex-align">
                        <image :src="表情" mode="widthFix"></image>
                        {{rule.title}}
                    </view>
                    <view class='desc' v-for="(item,index) in rule.content" :key="index">
                        {{item}}
                    </view>
                </view>
            </uni-popup>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                rule: {},
                questions: [{
                        title: '哈基米好可爱哈基米好',
                        content: ['1.哈基米好可爱哈基米好可爱哈基米好可爱',
                            '2.哈基米好可爱哈基米好可爱哈基米好可爱哈基米好可爱哈基米好可爱'
                        ]
                    }, {
                        title: '猜猜我是谁猜猜可爱',
                        content: ['1.猜猜我是谁猜猜我是谁。', '2.猜猜我是谁猜猜我是谁猜猜我是谁。']
                    },
                    {
                        title: '你好哇你好哇你好哇可爱',
                        content: ['1.你好哇你好哇你好哇。', '2.你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇']
                    }
                ],
                timer: null,
                rotate: true,
                isClose: false,
                hideFaq: false,
                showQuestion: false
            }
        },
        computed: {
            // 监听页面滚动
            meScrollY() {
                return this.$store.state.meScrollY;
            },
        },
        methods: {
            init() {
                this.timer = setInterval(() => {
                    this.rotate = !this.rotate
                }, 15000)
            },
            clearTimer() {
                clearInterval(this.timer)
                this.timer = null
            },
            openPopup(item) {
                this.rule = item
                this.isClose = false
                this.hideFaq = true
                setTimeout(() => {
                    this.$refs.popup.open()
                }, 1000)
            },
            closePopup() {
                this.isClose = true
                this.hideFaq = false
                this.showQuestion = false
                setTimeout(() => {
                    this.$refs.popup.close()
                }, 300)
            }
        }
    }
</script>

<style lang="scss" scoped>
    .faq {
        position: fixed;
        right: -100rpx;
        top: 46%;

        .content {
            image {

                &:first-child {
                    width: 80rpx;
                    z-index: 1;
                }

                &:last-child {
                    width: 120rpx;
                    margin-top: -10rpx;
                }
            }

            .rotate {
                // 图片翻转
                animation: rotate90 0.5s linear forwards 0.5s;

                @keyframes rotate90 {
                    0% {
                        transform: rotateY(0deg);
                    }

                    100% {
                        transform: rotateY(180deg);
                    }
                }
            }
        }

        .questions {
            background: red;
            position: absolute;
            right: -400rpx;
            top: 40%;
            opacity: 0;
            // 飞入
            animation: appear 0.5s linear forwards;

            @keyframes appear {
                0% {
                    opacity: 0;
                    right: -400rpx;
                }

                50% {
                    opacity: 0;
                    right: 200rpx;
                }

                100% {
                    opacity: 1;
                    right: 420rpx;
                }
            }

            view {
                position: absolute;
                top: 0;
                right: -420rpx;
                color: #000;
                font-size: 26rpx;
                white-space: nowrap;
                background-color: #FCDB66;
                border-radius: 25rpx;
                padding: 5rpx 20rpx;

                &:first-child {
                    animation: totop 0.5s linear forwards 0.5s;

                    @keyframes totop {
                        0% {
                            top: 0;
                            right: -420rpx;
                        }

                        100% {
                            top: -100rpx;
                            right: -290rpx;
                        }
                    }
                }

                &:nth-child(2) {
                    animation: tocenter 0.5s linear forwards 0.4s;

                    @keyframes tocenter {
                        0% {
                            right: -420rpx;
                        }

                        100% {
                            right: -260rpx;
                        }
                    }
                }

                &:last-child {
                    animation: tobottom 0.5s linear forwards 0.6s;

                    @keyframes tobottom {
                        0% {
                            top: 0;
                            right: -420rpx;
                        }

                        100% {
                            top: 100rpx;
                            right: -320rpx;
                        }
                    }
                }
            }
        }

        .hideQuestions {
            opacity: 1;
            // 飞出
            @keyframes disappear {
                0% {
                    right: -420rpx;
                    opacity: 1;
                }

                50% {
                    right: -620rpx;
                    opacity: 0;
                }

                100% {
                    right: -100%;
                    opacity: 0;
                }
            }

            view {

                &:first-child {
                    top: -100rpx;
                    animation: distotop 0.5s linear forwards, disappear 0.6s linear forwards 0.5s;

                    @keyframes distotop {
                        0% {
                            top: -100rpx;
                            right: -290rpx;
                        }

                        100% {
                            top: 0;
                            right: -420rpx;
                        }
                    }
                }

                &:nth-child(2) {
                    right: -290rpx;
                    animation: distocenter 0.5s linear forwards 0.2s, disappear 0.6s linear forwards 0.5s;

                    @keyframes distocenter {
                        0% {
                            right: -290rpx;
                        }

                        100% {
                            right: -420rpx;
                        }
                    }
                }

                &:last-child {
                    top: 100rpx;
                    right: -320rpx;
                    animation: distobottom 0.5s linear forwards 0.1s, disappear 0.6s linear forwards 0.5s;

                    @keyframes distobottom {
                        0% {
                            top: 100rpx;
                            right: -320rpx;
                        }

                        100% {
                            top: 0;
                            right: -420rpx;
                        }
                    }
                }
            }
        }
    }


    .rule-popup {

        ::v-deep .uni-popup__wrapper-box {
            background-color: transparent !important;
        }

        .hide-popup {
            // 缩放关闭
            animation: close 0.3s linear forwards;

            @keyframes close {
                0% {
                    transform: scaleY(1);
                }

                100% {
                    transform: scaleY(0);
                }
            }
        }

        &-content {
            position: relative;
            padding: 30rpx 0;
            animation: open 0.3s linear forwards;
            transform: scaleY(0);
            padding-bottom: 120rpx;
            // 缩放打开
            @keyframes open {
                0% {
                    transform: scaleY(0);
                }

                100% {
                    transform: scaleY(1);
                }
            }

            .close {
                position: absolute;
                top: -10rpx;
                right: 10rpx;
            }

            view {
                color: $base-color;
            }

            .title {
                text-align: center;
                font-size: 40rpx;
                margin-bottom: 20rpx;
                font-family: YouSheBiaoTiHei;

                image {
                    width: 140rpx;
                    margin-left: -15rpx;
                }
            }

            .desc {
                font-size: 26rpx;
                padding: 0 40rpx;
                margin-bottom: 30rpx;
            }
        }
    }

    .hideFaq {
        right: 20rpx;
        animation: hideFaq 0.5s linear forwards 1s;

        @keyframes hideFaq {
            0% {
                opacity: 1;
                right: 20rpx;
            }

            100% {
                opacity: 0;
                right: -100rpx;
            }
        }
    }
// 返回顶部出现
.scrollAppear {
    animation: scrollAppear 0.3s linear forwards;

    @keyframes scrollAppear {
        0% {
            opacity: 0;
            right: -100rpx;
        }

        100% {
            opacity: 1;
            right: 30rpx;
        }
    }
}

// 滚动消失
.scrollDisappear {
    animation: scrollDisappear 0.3s linear forwards;

    @keyframes scrollDisappear {
        0% {
            opacity: 1;
            right: 30rpx;
        }

        100% {
            opacity: 0;
            right: -100rpx;
        }
    }
}
</style>

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        meScrollY: 0
    },
    mutations: {
        setMeScrollY(state, value) {
            state.meScrollY = value;
        }
    }
})
export default store

页面滚动更新

this.$store.commit('setMeScrollY', e.detail.scrollTop)

效果图:pan.baidu.com/s/1mVzLnmbZ…