【技术实战】Vue功能样式实战【六】

发布时间 2023-08-12 23:39:22作者: 程序员天佑

 

<template>
    <ARow>
        <ACol style="background-color:#F1F4F5 ">
            <div class="info-card">
                <div class="info-title">
                    数据总和
                </div>
                <div class="info-value">
                    100
                </div>
            </div>

        </ACol>
    </ARow>
</template>
<script setup lang="ts">

</script>
<style scoped>
:deep(.info-card){
    width: 318px;
    height: 116px;
    background-color: #FFFFFF;
    box-shadow: 0px 2px 10px 1px rgba(23,179,163,0.07);
    border-radius: 4px;
}

:deep(.info-title){
    font-size: 18px;
    font-family: Microsoft YaHei;
    font-weight: 400;
    color: #333333;
    line-height: 21px;
    padding:20px 0 20px 30px;
}

:deep(.info-value){
    font-size: 36px;
    font-family: Microsoft YaHei;
    font-weight: bold;
    color: #333333;
    line-height: 21px;
    padding:0 0 0 30px;
}
</style>

 

<template>
    <div class="info-card">
        <div class="info-title">
            数据总和
        </div>
        <div class="info-value">
            100
        </div>
        <div class="animation-container">
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
        </div>
    </div>
</template>


<script setup lang="ts"></script>


<style scoped>
.info-card {
    width: 318px;
    height: 200px;
    background-color: #17b3a3;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
}


.info-title {
    font-size: 24px;
    font-weight: bold;
    color: #FFFFFF;
}


.info-value {
    font-size: 48px;
    font-weight: bold;
    color: #FFFFFF;
}


.animation-container {
    display: flex;
    position: absolute;
    bottom: 25px;
}


.circle {
    width: 10px;
    height: 10px;
    background-color: #FFFFFF;
    border-radius: 50%;
    margin: 0 4px;
    transform: scale(0);
    animation: pulse 1.5s infinite cubic-bezier(0.215, 0.61, 0.355, 1) alternate;
}


.circle:nth-child(1) {
    animation-delay: 0.1s;
}


.circle:nth-child(2) {
    animation-delay: 0.2s;
}
.circle:nth-child(3) {
    animation-delay: 0.3s;
}
.circle:nth-child(4) {
    animation-delay: 0.4s;
}
.circle:nth-child(5) {
    animation-delay: 0.5s;
}
.circle:nth-child(6) {
    animation-delay: 0.6s;
}


@keyframes pulse {
    0% {
        opacity: 0;
        transform: scale(0);
    }
    50% {
        opacity: 1;
        transform: scale(1);
    }
    100% {
        opacity: 0;
        transform: scale(0);
    }
}
</style>

 三

<template>
    <div class="info-card">
        <div class="info-title">
            数据总和
        </div>
        <div class="info-value">
            100
        </div>
        <div class="animation-container">
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
            <div class="circle"></div>
        </div>
    </div>
</template>


<script setup lang="ts"></script>


<style scoped>
.info-card {
    width: 318px;
    height: 200px;
    background-color: rgba(23, 179, 163, 0.5);
    backdrop-filter: blur(10px);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    border: 1px solid rgba(255, 255, 255, 0.2);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.1) 75%, transparent 75%, transparent);
    background-size: 20px 20px;

}


.info-title {
    font-size: 24px;
    font-weight: bold;
    color: #FFFFFF;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}


.info-value {
    font-size: 48px;
    font-weight: bold;
    color: #FFFFFF;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}


.animation-container {
    display: flex;
    position: absolute;
    bottom: 25px;
}


.circle {
    width: 10px;
    height: 10px;
    background-color: #FFD700;
    border-radius: 50%;
    margin: 0 4px;
    transform: scale(0);
    animation: pulse 1.5s infinite cubic-bezier(0.215, 0.61, 0.355, 1) alternate;
}


.circle:nth-child(1) {
    animation-delay: 0.1s;
}


.circle:nth-child(2) {
    animation-delay: 0.2s;
}
.circle:nth-child(3) {
    animation-delay: 0.3s;
}
.circle:nth-child(4) {
    animation-delay: 0.4s;
}
.circle:nth-child(5) {
    animation-delay: 0.5s;
}
.circle:nth-child(6) {
    animation-delay: 0.6s;
}


@keyframes pulse {
    0% {
        opacity: 0;
        transform: scale(0);
    }
    50% {
        opacity: 1;
        transform: scale(1);
    }
    100% {
        opacity: 0;
        transform: scale(0);
    }
}
</style>

<template>
    <div class="home-component">
        <ARow style="padding:0 0 30px 0">
            <div class="info-card">
                <div class="info-title">
                    数据总和
                </div>
                <transition name="number-transition">
                    <div class="info-value" :class="{ init:init,changed: isNumberIncreased, decreased: isNumberDecreased }">
                        {{ animatedValue }}
                    </div>
                </transition>
                <div class="animation-container">
                    <div class="circle"></div>
                    <div class="circle"></div>
                    <div class="circle"></div>
                    <div class="circle"></div>
                    <div class="circle"></div>
                    <div class="circle"></div>
                </div>
            </div>
        </ARow>
        <ARow>
            <ACol span="10">
                <div class="button-container">
                    <a-button class="increase-button" type="primary" @click="addNumber">增加数值</a-button>
                </div>
            </ACol>
            <ACol span="4">
            </ACol>
            <ACol span="10">
                <div class="button-container">
                    <a-button class="decrease-button" type="primary" @click="minNumber">减少数值</a-button>
                </div>
            </ACol>
        </ARow>
    </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';

const value = ref(100);
const isNumberIncreased = ref(false);
const isNumberDecreased = ref(false);

const animatedValue = ref(value.value);
const init=ref(true)


const addNumber = () => {
        const startValue = value.value;
        const endValue = startValue + 10;
        animateNumber(startValue, endValue);
        value.value = endValue;
        init.value=false;
    isNumberDecreased.value = false;

    isNumberIncreased.value = true;

};

const minNumber = () => {
        const startValue = value.value;
        const endValue = startValue - 10;
        animateNumber(startValue, endValue);
        value.value = endValue;
        init.value=false;
    isNumberIncreased.value = false;

    isNumberDecreased.value = true;
};
const animateNumber = (startValue:any, endValue:any) => {
    const duration = 1000; // 动画持续时间,单位为毫秒
    const frameRate = 10; // 每秒帧数
    const totalFrames = duration / (1000 / frameRate);
    const frameIncrement = (endValue - startValue) / totalFrames;

    let currentFrame = 0;
    const timer = setInterval(() => {
        currentFrame++;
        animatedValue.value = Math.round(startValue + frameIncrement * currentFrame);

        if (currentFrame === totalFrames) {
            clearInterval(timer);
        }
    }, 1000 / frameRate);
};

watch(value, () => {
    animatedValue.value = value.value;
});
</script>

<style scoped>
.home-component {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.info-card {
    width: 318px;
    height: 200px;
    background-color: rgba(23, 179, 163, 0.5);
    backdrop-filter: blur(10px);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    border: 1px solid rgba(255, 255, 255, 0.2);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    background-image: linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.1) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.1) 50%,
        rgba(255, 255, 255, 0.1) 75%,
        transparent 75%,
        transparent
    );
    background-size: 20px 20px;
}

.info-title {
    font-size: 24px;
    font-weight: bold;
    color: #ffffff;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.info-value {
    font-size: 48px;
    font-weight: bold;
    color: #ffffff;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.info-value.init {
    color: #ffffff;
    transform: scale(1.2);
}
.info-value.changed {
    color: #13c40d;
    transform: scale(1.2);
}
.info-value.decreased {
    color: #eb5766;
    transform: scale(1.2);
}
.animation-container {
    display: flex;
    position: absolute;
    bottom: 25px;
}

.circle {
    width: 10px;
    height: 10px;
    background-color: #ffd700;
    border-radius: 50%;
    margin: 0 4px;
    transform: scale(0);
    animation: pulse 1.5s infinite cubic-bezier(0.215, 0.61, 0.355, 1) alternate;
}

.circle:nth-child(1) {
    animation-delay: 0.1s;
}

.circle:nth-child(2) {
    animation-delay: 0.2s;
}

.circle:nth-child(3) {
    animation-delay: 0.3s;
}

.circle:nth-child(4) {
    animation-delay: 0.4s;
}

.circle:nth-child(5) {
    animation-delay: 0.5s;
}

.circle:nth-child(6) {
    animation-delay: 0.6s;
}

@keyframes pulse {
    0% {
        opacity: 0;
        transform: scale(0);
    }
    50% {
        opacity: 1;
        transform: scale(1);
    }
    100% {
        opacity: 0;
        transform: scale(0);
    }
}

.button-container {
    display: flex;
    justify-content: center;
    padding: 30px 0;
    animation: bounce 2s infinite;
    animation-delay: 1s;
}

.increase-button,
.decrease-button {
    font-size: 16px;
    font-weight: bold;
    text-transform: uppercase;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
    border: none;
    transform: scale(1.05) rotate(360deg);
    transition: transform 1s;
    border-radius: 5px;
}

.increase-button {
    background-color: #38b2ac;
    margin-right: 10px;
}

.decrease-button {
    background-color: #eb5766;
    margin-left: 10px;
}

.increase-button:hover,
.decrease-button:hover {
    transform: scale(1.05);
    box-shadow: 0 2px 15px rgba(0, 0, 0, 0.4);
}
</style>