• vue:实现丝滑上传进度条


    一、效果展示

    缓若江海凝清光

    .

    二、代码

    1. const uploadProgress = ref(); //上传进度
    2. //进度丝滑更新
    3. //进度,时常
    4. const ProgressChange = (targetPercent: number, duration: number) => {
    5. //performance.now() 是浏览器提供的一个高性能时间 API,它返回一个 DOMHighResTimeStamp,
    6. //这个时间戳提供了当前页面从加载到现在所经过的毫秒数,具有很高的精度,适合用来测量脚本执行时间、动画帧间隔等
    7. const startTime = performance.now();
    8. //获取当前进度
    9. const startPercent = uploadProgress.value;
    10. const step = (currentTime: number) => {
    11. // 计算当前进度
    12. const elapsedTime = currentTime - startTime;
    13. // 修改进度条的百分比实现动画效果
    14. let currentPercent = easeInOut(
    15. elapsedTime,
    16. startPercent,
    17. targetPercent - startPercent,
    18. duration
    19. );
    20. // 确保百分比不超过100且不小于0
    21. currentPercent = Math.min(Math.max(currentPercent, 0), 100);
    22. // 更新进度条
    23. uploadProgress.value = Math.round(currentPercent);
    24. // 如果动画未结束,继续执行动画
    25. if (currentPercent < 100 && elapsedTime < duration) {
    26. requestAnimationFrame(step);
    27. } else {
    28. uploadProgress.value = Math.round(targetPercent); // 确保最终值准确无误
    29. }
    30. };
    31. // 使用函数使动画更加平滑
    32. const easeInOut = (t: number, b: number, c: number, d: number) => {
    33. t /= d / 2;
    34. if (t < 1) return (c / 2) * t * t * t + b;
    35. t -= 2;
    36. return (c / 2) * (t * t * t + 2) + b;
    37. };
    38. requestAnimationFrame(step);
    39. };
    40. //选择文件
    41. const handleFileChange = async (event: any) => {
    42. uploadProgress.value = 0;
    43. const file = event.target.files[0];
    44. fileNmae.value = file.name;
    45. if (file) {
    46. const reader = new FileReader();
    47. const updateProgress = (event: ProgressEvent) => {
    48. if (event.lengthComputable) {
    49. const totalDuration = 1000; // 1秒,单位为毫秒
    50. const percentComplete = (event.loaded / event.total) * 100;
    51. ProgressChange(percentComplete, totalDuration);
    52. }
    53. };
    54. reader.readAsDataURL(file);
    55. reader.onprogress = updateProgress;
    56. reader.onload = (e) => {
    57. if (typeof e.target?.result == "string") {
    58. imageUrl.value = e.target.result;
    59. }
    60. reader.onprogress = null;
    61. fileInfo.size = Number((file.size / 1024).toFixed(2));
    62. };
    63. }

    三、实现原理

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

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

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

  • 相关阅读:
    五笔会消亡吗
    【计算机网络】习题(三)—— 数据链路层
    GO语言开山篇(一):学习方向
    【原创】浅谈指针(十)链表的写法
    JVM虚拟机栈的五道面试题
    React ajax
    [SUCTF 2019]Pythonginx
    0x02. Spring Boot 3 之SpringBoot 版本升级最佳实践指南
    PMP 11.27 考试倒计时8天!
    无线信号测试软件哪种好用
  • 原文地址:https://blog.csdn.net/qq_45820271/article/details/139336399