进度条动画显示

第一步

<template>
    <!-- 进度条组件 -->
    <div class="progress-bar">
        <!-- 背景 -->
        <div class="bg"></div>
        <!-- 进度条 -->
        <div class="bar" :style="{ width: progress + '%' }"></div>
        <!-- 进度显示文本 -->
        <div class="label">{{ progress }}%</div>
    </div>
</template>

第二步

子组件中

<script lang="ts" setup>
import { ref, reactive, onMounted, defineProps } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const props = defineProps({
    progress: {
        type: Number,
        required: true
    }
})

const route = useRoute()
const router = useRouter()

const progress = ref<any>(0)
progress.value = props.progress
const isPlaying = ref<any>(false)
const isCompleted = ref<any>(false)

onMounted(() => {
    start()
})

// 开始进度动画
const start = () => {
    isPlaying.value = true;

    // 开始从0%到90%的动画,并在完成后继续到100%
    animateProgress(100).then(() => {
        if (!isCompleted.value) {
            animateProgress(100);
        }
    }).catch((error) => {
        console.log('Progress error', error);
        finish()
    });

}

const animateProgress = (target: number) => {
    // 返回一个Promise对象,用于异步操作
    return new Promise((resolve: any, reject: any) => {
        // 初始化起始值、目标值和动画持续时间
        let start = progress.value;
        const end = target;
        const duration = (target - start) * 150;

        // 执行动画的函数
        const doAnimation = () => {
            // 计算动画流逝的时间
            const elapsed = Date.now() - startTime;
            // 计算当前进度百分比
            const Progress = Math.min(elapsed / duration, 1);

            // 更新进度值
            progress.value = start + ((end - start) * Progress);

            // 可选:保留小数点后两位或不保留toFixed(填入0-2);
            // 例如:保留俩位就(start + ((end - start) * Progress)).toFixed(2);
            // 例如:不保留位就(start + ((end - start) * Progress)).toFixed(0);

            // 判断动画是否完成
            if (Progress === 1) {
                resolve();
            } else if (isCompleted.value) {
                resolve();
            } else {
                // 继续执行下一帧动画
                requestAnimationFrame(doAnimation);
            }
        };

        // 记录动画开始时间
        const startTime = Date.now();
        // 启动第一帧动画
        requestAnimationFrame(doAnimation);
    });
}

const finish = () => {
    isCompleted.value = true;
    progress.value = 100;
}
</script>

父组件

<template>
    <div>
        <Porgress :progress="0" />
    </div>
</template>

<script lang="ts" setup>
import Porgress from '@/components/Progress.vue';
</script>

子组件样式

<style lang="scss" scoped>
.progress-bar {
    position: relative;
    width: 50%;
    height: 8px;
    margin: 500px auto;
}

.bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #ccc;
    border-radius: 5px;
}

.bar {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    border-radius: 5px;
    background-color: #409eff;
    transition: width 0.5s;
}

.label {
    position: absolute;
    top: -20px;
    left: calc(100% + 5px);
    color: #333;
    font-size: 12px;
}
</style>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值