我的编程空间,编程开发者的网络收藏夹
学习永远不晚

利用svg实现带加载进度的loading

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

利用svg实现带加载进度的loading

什么是svg

svg是基于XML,由World Wide Web Consortium (W3C)联盟开发的一种开放标准的矢量图形语言,可让你设计激动人心的、高分辨率的Web图形页面。

可能有人不知道XML是什么,你只需知道他和html一样也是一种页面结构。他们同样都是由W3C开发的,只不过xml用来设计web图形,html用来构建web页面。

loading就属于web图形的一种,所以是可以使用基于XML的svg来实现的。同时因为他和html是同一级别的,所以兼容性不必多说。

用到svg元素、属性介绍

circle标签

circle是svg中的一个基础标签,类似于html的div。不同的是div是长方形,circle是圆形。

他有三个专有属性也是基本参数:cxcyr。前两个表示圆心的水平、垂直坐标,r表示圆的半径。

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <circle cx="50" cy="50" r="50"/>
</svg>

text标签

text元素定义了一个由文字组成的图形,可以理解为专门用来装文字的div。

tspan标签

在text元素中,利用内含的tspan元素,可以调整文本和字体的属性以及当前文本的位置、绝对或相对坐标值。

stroke-dasharray属性

stroke-dasharray属性是实现loading最关键的一个属性。

  • 这个属性的作用是为他所在的元素画一条线,这条线的位置相当于是border的概念。
  • 与border不同的是,他所传入的值只用来表示线的类型类似于border-style,没有颜色和宽度。
  • 它用来表示线型的方法不是采用 solid dashed 等这样的名称来命名,而是通过一段有间隔的数字来分别表示线的长度和间隔长度。
<svg width="200" height="200" viewPort="0 0 200 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <line stroke-dasharray="5, 5"              x1="10" y1="10" x2="190" y2="10" />
    <line stroke-dasharray="5, 10"             x1="10" y1="30" x2="190" y2="30" />
    <line stroke-dasharray="10, 5"             x1="10" y1="50" x2="190" y2="50" />
    <line stroke-dasharray="5, 1"              x1="10" y1="70" x2="190" y2="70" />
    <line stroke-dasharray="1, 5"              x1="10" y1="90" x2="190" y2="90" />
    <line stroke-dasharray="0.9"               x1="10" y1="110" x2="190" y2="110" />
    <line stroke-dasharray="15, 10, 5"         x1="10" y1="130" x2="190" y2="130" />
    <line stroke-dasharray="15, 10, 5, 10"     x1="10" y1="150" x2="190" y2="150" />
    <line stroke-dasharray="15, 10, 5, 10, 15" x1="10" y1="170" x2="190" y2="170" />
    <line stroke-dasharray="5, 5, 1, 5"        x1="10" y1="190" x2="190" y2="190" />

    <style><![CDATA[
    line{
        stroke: black;
        stroke-width: 2;
    }
    ]]></style>
</svg>

可以看出第一行线的长度和间隔长度都是5。第二行线长是5间隔长度是10,因此空白是实线的2倍。第三行线长是10间隔是5,因此实心是空白的2倍。后面的以此类推。

stroke-linecap属性

stroke-linecap表示线头的类型。这是svg独有的特性,他有三个常见属性如下:

<svg viewBox="0 0 6 6" xmlns="http://www.w3.org/2000/svg">
  <line x1="1" y1="1" x2="5" y2="1" stroke="black" stroke-linecap="butt" />
  <line x1="1" y1="3" x2="5" y2="3" stroke="black" stroke-linecap="round" />
  <line x1="1" y1="5" x2="5" y2="5" stroke="black" stroke-linecap="square" />
    <!--线的真实长度-->
  <path d="M1,1 h4 M1,3 h4 M1,5 h4" stroke="pink" stroke-width="0.025" />
</svg>

这里需要特别注意的是其中粉色线的长度才是真实线的长度,当stroke-linecap的值为round或square时,视觉上会使线的头尾加长。

其他属性

  • stroke-width: 表示线的宽度,类似于border-width
  • stroke: 表示线的颜色,类似于border-color
  • fill 表示填充色,类似于background-color,不同的是只要是svg的元素就可以使用他填充颜色,包括文字标签。当不设置时默认值为黑色,设置为none时为透明。

circle标签添加stroke-width的效果

<svg width="100" height="100">
    <circle 
        cx="50" cy="50" r="40" 
        stroke-width="10" stroke="red" fill="green" stroke-dasharray="50 252"
    ></circle>
</svg>

这里注意默认情况下是从圆的最右边顺时针开始画线,而不是最上边

实现loading

实现原理

通过动态控制进度圆stroke-dasharray属性的第一个参数大小,来表示loading进度。

这么说可能很难理解,看完实现步骤再回来看就很好理解了。

实现步骤

1.在svg标签中创建两个圆,为他们设置相同的圆心(cx、cy)、半径r、边框宽度stroke-width。满足 cx + r + stroke-width = svg的宽。

2.为两个圆分别设置他们的边框颜色stroke,这里需要注意的是因为两个圆圆心、半径相同所以第二个圆会覆盖到第一个圆上面。

我们将覆盖在上面的圆(代码中后写的circle)叫做进度圆,他的颜色设置为进度条的颜色。

将被盖住的圆(代码中第一个写的circle)叫做背景圆,他的颜色设置为圆环的背景色。

此时页面应该显示的是100%进度的loading圆环,如下:

<svg width="100" height="100">
    <!--背景圆-->
    <circle cx="50" cy="50" r="40" stroke-width="10" stroke="#eee" fill="none"></circle>
    <!--进度圆-->
    <circle cx="50" cy="50" r="40" stroke-width="10" stroke="red" fill="none"
    ></circle>
</svg>

3.添加进度文字,需要在circle下方添加一个text文本框,在其中放入两个tspan元素。一个用来更新进度,一个放%。

<svg width="100" height="100">
    <circle cx="50" cy="50" r="40" stroke-width="10" stroke="#eee" fill="none"></circle>
    <circle cx="50" cy="50" r="40" stroke-width="10" stroke="red" fill="none"></circle>
    <text x="50" y="56" text-anchor="middle">
        <tspan>100</tspan><tspan>%</tspan>
    </text>
</svg>

这里需要注意的是,text标签的y属性设置成50会默认偏上,经过我的测试加上其字体大小的三分之一效果刚刚好。

4.使用计时器模拟加载进度并且动态更新进度圆stroke-dasharray属性的第一个参数大小 。这里采用react来模拟计时器。

// app.js
import {useState, useEffect} from 'react';
import Loading from "./loading";

function App() {
  const [percent, setPrecent] = useState(0);
    useEffect(() => {
      let timer = setInterval(() => {
        setPrecent(percent => {
          percent+= 5;
          if(percent === 100) {
            clearInterval(timer);
          }
          return percent;
        });
      }, 200)
      return () => clearInterval(timer);
    }, [])
  
  return (
    <div >
      <Loading percent={percent} />
    </div>
  );
}
export default App;
// loading/index.jsx
import styles from './style.module.scss';
export default function Loading({
    size = 100,
    r = 40,
    strokeWidth = 10,
    stroke = 'red',
    strokeBg = '#ccc',
    strokeLinecap = 'butt',
    percent = 0,
    fontSize = '16',
    fontColor = '#6b778c'
}) {
    let perimeter = 2 * Math.PI * r;
    let strokeDasharray = `${Math.floor(percent / 100 * perimeter)} ${perimeter}`;

    return (
        <svg className={styles.svg} width={size} height={size}>
            // 背景圆
            <circle 
                cx={size / 2} cy={size / 2} r={r} strokeWidth={strokeWidth} stroke={strokeBg}
            ></circle>
            // 进度圆
            <circle
                className={styles.show}
                cx={size / 2} cy={size / 2} r={r} strokeWidth={strokeWidth} stroke={stroke}
                strokeDasharray={strokeDasharray} strokeLinecap={strokeLinecap}
            ></circle>
            <text x={size / 2} y={size / 2 + fontSize / 3} fill={fontColor} fontSize={fontSize} textAnchor="middle">
                <tspan>{percent}</tspan><tspan>%</tspan>
            </text>
        </svg>
    );
}

注意样式中要加上逆时针旋转90度,因为在圆上画线时默认从圆的最右边开始顺时针画。而我们的要求是从最上方开始顺时针画,所以要逆时针旋转90deg。

// style.module.scss
@keyframes rotate {
    0% {
        transform: rotate(-90deg); 
    }
    25% {
        transform: rotate(0deg);
    }
    50% {
        transform: rotate(90deg); 
    }
    75% {
        transform: rotate(180deg);
    }
    100% {
        transform: rotate(270deg);
    }

}
svg {
    circle {
        fill: none;
    }
    .show {
        // 逆时针旋转90deg
        transform: rotate(-90deg);
        transform-origin: center;
        transition: all 1s;
        animation: rotate 1s linear infinite;
    }
}

此时效果如图,已经达到了我们想要的效果。

loding优化

采用默认的线头(butt)时,边缘很尖给人一种很尖锐的感觉,可以通过给strokeLinecap传入round属性将线头变为圆形,这样就看上去更加流畅了。

strokeLinecap等于round时的bug

上面提到将线头strokeLinecap优化为round,但是优化完会产生两个不容易被发现的bug。产生这两个bug的根本原因就在于前面提到过的:

这里需要特别注意的是其中粉色线的长度才是真实线的长度,当stroke-linecap的值为round或square时,视觉上会使线的头尾加长。

0%时的问题

这个问题非常明显,我进度明明是0,确有进度明显不合理。产生这种问题的原因就是当strokeLinecap不为默认值butt时,首尾会超出来一截。

解决问题的方式也非常简单,那就是当strokeLinecap不为默认值butt 且 进度为0时让strokeLinecap属性等于默认值。

let cap = (strokeLinecap !== 'butt' && percent !== 0) ? strokeLinecap : 'butt';

// 在进度圆上将strokeLinecap属性传入的值替换为cap
//  <circle strokeLinecap={cap} ></circle>

96%时的问题

与上面0%问题类似,由于默认多出来的一截会导致进度还没有到100%,只有96%时就已经连到了一起,给人以100%的效果。

之所以会产生这种问题,是因为0%时明明没有进度却占用了一部分的进度值。这就导致原本100%进度对应100%周长变为了100%进度对应100%周长减去strokeLinecap额外带来的周长。

根据观察strokeLinecap额外带来的周长约等于线的宽度strokeWidth,所以解决方案如下。

let strokeDasharray = "";
if(strokeLinecap === 'butt') {
    // 当前是默认状态,采用全周长计算
    strokeDasharray=`${Math.floor(percent / 100 * perimeter)} ${perimeter}`;
} else {
    // 需要剪掉strokeLinecap多出来的那部分
    strokeDasharray=`${Math.floor(percent / 100 * (perimeter - strokeWidth))} ${perimeter}`;
}

进度条loading应用场景

只要带有进度的地方都可以使用它,比如常见的下载进度、xxx完成进度、加载页面进度。也可以动态的加载从0到某个进度,常用于金融中自己的持仓占比等。

到此这篇关于利用svg实现带加载进度的loading的文章就介绍到这了,更多相关svg带加载进度loading内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

利用svg实现带加载进度的loading

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

利用svg实现带加载进度的loading

svg是基于XML,由World Wide Web Consortium (W3C)联盟开发的一种开放标准的矢量图形语言,可让你设计激动人心的、高分辨率的Web图形页面。本文将使用svg实现一个带加载进度的loading,需要的可以参考一下
2022-11-13

利用Glide怎么实现一个加载进度条功能

利用Glide怎么实现一个加载进度条功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。使用Glide.with(MainActivity.this).using(new Pro
2023-05-31

Android 进度条 ProgressBar的实现代码(隐藏、出现、加载进度)

初识进度条ProgressBar 软件:Android Studio 实现:1.点击按钮,进度条隐藏;再次点击,进度条出现。循环 2.点击按钮,水平进度条进度呈现并+10,此处进度条max为100。循环 1.圆形进度条 练习
2022-06-06

使用css实现android系统的loading加载动画

小编给大家分享一下使用css实现android系统的loading加载动画,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!web常用的loading图标有2种, 一
2023-06-08

Android如何实现简单的加载进度条

这篇文章将为大家详细讲解有关Android如何实现简单的加载进度条,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Android是什么Android是一种基于Linux内核的自由及开放源代码的操作系统,主要
2023-06-14

怎么使用JS和CSS实现加载进度条的效果

这篇文章主要介绍“怎么使用JS和CSS实现加载进度条的效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用JS和CSS实现加载进度条的效果”文章能帮助大家解决问题。准备软件:HBuilderX
2023-07-04

使用Timer实现网页匀速加载的进度条样式

在使用WebView加载网页时有时候网速等原因加载比较慢时,为了避免在加载网页的时候出现一片空白的区域,给用户很不好的体验感,我们往往在加载的时候添加一个进度条,使用户直观的感受到网页加载的进度,通常我们可以通过WebChromeClien
2023-05-31

怎么用vue实现页面加载时的进度条功能

这篇“怎么用vue实现页面加载时的进度条功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么用vue实现页面加载时的进度条
2023-07-04

基于JavaScript实现永远加载不满的进度条

各位开发大佬,平时肯定见到过这种进度条吧,一直在加载,但等了好久都是在99%,那如何用JavaScript实现这一效果呢,下面就来和大家详细讲讲
2023-05-15

如何使用CSS制作网页加载进度条的实现步骤

如何使用CSS制作网页加载进度条的实现步骤在现代网页设计中,加载速度对于用户体验至关重要。为了提升用户体验,可以使用CSS制作网页加载进度条,让用户清晰地了解网页加载进度。本文将介绍使用CSS制作网页加载进度条的实现步骤,并提供具体的代码示
2023-10-26

如何使用JS+CSS实现一个简单加载进度条的效果

这篇文章主要讲解了“如何使用JS+CSS实现一个简单加载进度条的效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用JS+CSS实现一个简单加载进度条的效果”吧!一、前言我们经常在网页
2023-06-15

如何使用CSS实现带箭头的流程进度条

这篇文章将为大家详细讲解有关如何使用CSS实现带箭头的流程进度条,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先写出一个基本的样式。.cssNav li{ padding: 0px 20px;
2023-06-08

如何利用css3实现进度条效果及动态添加百分比

这篇文章主要介绍了如何利用css3实现进度条效果及动态添加百分比,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。代码:2023-06-08

Android自定义View实现圆形加载进度条效果的方法

这篇文章将为大家详细讲解有关Android自定义View实现圆形加载进度条效果的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。View仿华为圆形加载进度条效果图实现思路可以看出该View可分为三个部分
2023-05-30

编程热搜

目录