vue:实现丝滑上传进度条

一、效果展示

缓若江海凝清光

.

二、代码

TypeScript 复制代码
const uploadProgress = ref(); //上传进度

//进度丝滑更新
//进度,时常
const ProgressChange = (targetPercent: number, duration: number) => {
  //performance.now() 是浏览器提供的一个高性能时间 API,它返回一个 DOMHighResTimeStamp,
  //这个时间戳提供了当前页面从加载到现在所经过的毫秒数,具有很高的精度,适合用来测量脚本执行时间、动画帧间隔等
  const startTime = performance.now();
  //获取当前进度
  const startPercent = uploadProgress.value;

  const step = (currentTime: number) => {
    // 计算当前进度
    const elapsedTime = currentTime - startTime;
    // 修改进度条的百分比实现动画效果
    let currentPercent = easeInOut(
      elapsedTime,
      startPercent,
      targetPercent - startPercent,
      duration
    );

    // 确保百分比不超过100且不小于0
    currentPercent = Math.min(Math.max(currentPercent, 0), 100);

    // 更新进度条
    uploadProgress.value = Math.round(currentPercent);

    // 如果动画未结束,继续执行动画
    if (currentPercent < 100 && elapsedTime < duration) {
      requestAnimationFrame(step);
    } else {
      uploadProgress.value = Math.round(targetPercent); // 确保最终值准确无误
    }
  };

  // 使用函数使动画更加平滑
  const easeInOut = (t: number, b: number, c: number, d: number) => {
    t /= d / 2;
    if (t < 1) return (c / 2) * t * t * t + b;
    t -= 2;
    return (c / 2) * (t * t * t + 2) + b;
  };
  requestAnimationFrame(step);
};

//选择文件
const handleFileChange = async (event: any) => {
  uploadProgress.value = 0;
  const file = event.target.files[0];
  fileNmae.value = file.name;
  if (file) {
    const reader = new FileReader();
    const updateProgress = (event: ProgressEvent) => {
      if (event.lengthComputable) {
        const totalDuration = 1000; // 1秒,单位为毫秒
        const percentComplete = (event.loaded / event.total) * 100;
        ProgressChange(percentComplete, totalDuration);
      }
    };
    reader.readAsDataURL(file);
    reader.onprogress = updateProgress;
    reader.onload = (e) => {
      if (typeof e.target?.result == "string") {
        imageUrl.value = e.target.result;
      }
      reader.onprogress = null;
      fileInfo.size = Number((file.size / 1024).toFixed(2));
    };
  }

三、实现原理

1.通过performance.now()获取动画的时间戳,用于创建流畅的动画。

2.通过一个缓动函数来实现动画的过渡效果。

3.通过requestAnimationFrame这个API来更新动画帧,优化显示效果。

相关推荐
紫禁玄科几秒前
Shai-Hulud:npm生态的自我复制蠕虫风暴
前端·npm·node.js
东风破_15 分钟前
后端API没写好,前端难道干等着吗?
前端
用户9385156350730 分钟前
从前后端分离到前端接口工程:React + MockJS + Vite 解析
前端·后端·全栈
用户9385156350738 分钟前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformers.js 全链路实战(三)
前端·react.js·typescript
excel1 小时前
当前端行情变差,我们为什么还要坚持?
前端
鸿是江边鸟,曾是心上人1 小时前
快速搭建HTTPS本地开发环境
前端
To_OC2 小时前
写了 5 个表单 Demo 后,我终于彻底搞懂了 React 受控与非受控组件
前端·react.js·前端框架
Sterting2 小时前
第9课 Vue Router 路由
前端·vue.js
用户059540174462 小时前
LangChain Memory 测试踩坑实录:用 pytest 自动化回归对话记忆,我折腾了整整一个周末
前端·css
kyriewen3 小时前
Claude Code后天起默认Auto模式了——我第一时间改了这6个设置
前端·ai编程·claude