首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >SVG进度条

SVG进度条
EN

Stack Overflow用户
提问于 2016-07-18 20:57:31
回答 4查看 7.6K关注 0票数 16

我有一个需求,需要动态加载js文件,并通过SVG图标显示加载文件的进度。SVG图标将作为进度条,从下到上线性填充一种颜色。

这是codepen

代码语言:javascript
复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">

  <path fill="transparent" stroke="black" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</svg>

我计划让这个图标独立,这样我只会动态传递百分比值。

不知何故,我能够完成动画,但不能保持svg的边框或轮廓。这是code

代码语言:javascript
复制
#progressMove {
  transition: .3s y;
}
#progressMove:hover {
  y: 60%;
}
代码语言:javascript
复制
<svg id="kenseoProgress" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
  <defs>
    <mask id="bubbleKenseo">
      <path fill="red" stroke="black" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
    </mask>
  </defs>
  <g x="0" y="0" width="79.36px" height="93.844px" mask="url(#bubbleKenseo)" height="100">
    <rect id="progressMove" x="0" y="0%" width="100%" height="100%" fill="blue" stroke="black" />
  </g>
</svg>

所以,我遇到的问题是:

  • 无法维护SVG
  • 的边框,无论我添加什么颜色都有某种我无法保持浏览器兼容性的不透明度: IE11+,chrome,safari和firefox

附言:我不想使用SMIL动画。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-10-04 03:37:03

首先,您要使用clip-path,或者将mask填充设置为白色以获得100%的不透明度:mask用作灰度alpha通道,红色填充颜色会导致不透明度发生变化。

至于笔划,您希望将其添加为不受剪切影响的单独元素。(您可以在defsuse__中重用该路径,我只是在这里复制粘贴了它)

代码语言:javascript
复制
#progressMove {
  transition: .3s y;
}
#progressMove:hover {
  y: 60%;
}
代码语言:javascript
复制
<svg id="kenseoProgress" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
  <defs>
    <clipPath id="bubbleKenseo">
      <path d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
    </clipPath>
  </defs>
  <path stroke="black" stroke-width="1" fill="transparent" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
  <g x="0" y="0" width="79.36px" height="93.844px" clip-path="url(#bubbleKenseo)" height="100">
    <rect id="progressMove" x="0" y="0%" width="100%" height="100%" fill="blue" stroke="black" />
  </g>
</svg>

票数 3
EN

Stack Overflow用户

发布于 2016-09-27 23:50:54

CHROME/SAFARI解决方案

使用CSS属性transformcounter-increment,您可以实现填充和数字递增。

代码片段

代码语言:javascript
复制
for (var i = 0; i < 100; i++) {
  setTimeout(function() {
    $(".progress-container p").append("<span>");
  }, i * 20);
}
代码语言:javascript
复制
pattern #progressMove {
  transform: translateY(100%);
  color: purple;
  animation: progressBar 2s steps(100, end) forwards;
}
@keyframes progressBar {
  to {
    transform: translateY(0);
  }
}
.progress-container {
  margin: 0;
  display: inline-block;
  position: relative;
  counter-reset: progress;
}
.progress-container figcaption {
  position: absolute;
  top: 40%;
  left: 50%;
  transform: translate(-40%, -50%);
}
.progress-container p {
  margin: 0;
  font-weight: bold;
}
.progress-container span {
  counter-increment: progress;
}
.progress-container p::after {
  content: counter(progress)"%";
}
代码语言:javascript
复制
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<figure class="progress-container">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
    <pattern id="progress" x="0" y="0" width="79.36" height="93.844" patternUnits="userSpaceOnUse">
      <rect id="progressMove" x="0" y="0" width="100%" height="100%" stroke="none" fill="currentColor" />
    </pattern>
    <path fill="url(#progress)" stroke="#000" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
  </svg>
  <figcaption>
    <p>

    </p>
  </figcaption>
</figure>

注意:

如果我能给出一个更好的解决方案来覆盖浏览器支持,我会更新。

编辑:

根据 answer,您还必须将背景的颜色更改为其父背景的颜色。

整个组件将是figure元素,遗憾的是,spritesheet中的符号仅用于提供路径和背景。

注意:此版本中删除了jQuery。

代码语言:javascript
复制
for (var i = 0; i < 100; i++) {
  setTimeout(function() {
    var progressCounter = document.querySelector(".progress__counter"),
      number = document.createElement("span");
    progressCounter.appendChild(number);
  }, i * 20);
}
代码语言:javascript
复制
#spritesheet {
  display: none;
}
.icon {
  display: inline-block;
  width: 1em;
  height: 1em;
}
.icon-bubble {
  font-size: 7em;
  color: white;
}
.progress-container {
  margin: 0;
  display: inline-block;
  position: relative;
  counter-reset: progress;
  overflow: hidden;
  line-height: 0;
}
.progress__inner {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}
.progress__fill {
  background-color: purple;
  height: 100%;
  transform: translateY(100%);
  animation: progressFill 2s steps(100, end) forwards;
}
@keyframes progressFill {
  to {
    transform: translateY(0);
  }
}
.progress__counter {
  position: absolute;
  top: 40%;
  left: 50%;
  transform: translate(-40%, -50%);
  margin: 0;
  font-weight: bold;
}
.progress__counter span {
  counter-increment: progress;
}
.progress__counter::after {
  content: counter(progress)"%";
}
代码语言:javascript
复制
<figure class="progress-container">
  <svg class="icon icon-bubble">
    <use xlink:href="#icon-bubble"></use>
  </svg>
  <figcaption class="progress__inner">
    <div class="progress__fill"></div>
    <p class="progress__counter"></p>
  </figcaption>
</figure>

<svg id="spritesheet">
  <symbol id="icon-bubble" viewBox="0 0 79.36 93.844">
    <title>Loading Bubble</title>
    <path id="bubble-cover" fill="currentColor" stroke="#000" d="M-10,-10 100,-10 100,100 -10,100 -10,-10  50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
  </symbol>
</svg>

测试:

  • Chrome 53
  • IE10
  • Edge
  • FireFox 47
  • IOS 10 Safari

游乐场

代码语言:javascript
复制
for (var i = 0; i < 100; i++) {
  setTimeout(function() {
    var progressCounter = document.querySelector(".progress__counter"),
      number = document.createElement("span");
    progressCounter.appendChild(number);
  }, i * 20);
}
代码语言:javascript
复制
#spritesheet {
  display: none;
}
.icon {
  display: inline-block;
  width: 1em;
  height: 1em;
}
.icon-bubble {
  font-size: 7em;
  color: white;
}
.progress-container {
  margin: 0;
  display: inline-block;
  position: relative;
  counter-reset: progress;
  overflow: hidden;
  line-height: 0;
}
.progress__inner {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}
.progress__fill {
  background-color: purple;
  height: 100%;
  transform: translateY(100%);
  animation: progressFill 2s steps(100, end) forwards, progressFillColor 100ms linear 2s forwards;
  position: relative;
}
@keyframes progressFill {
  to {
    transform: translateY(0);
  }
}
@keyframes progressFillColor {
  to {
    background-color: green;
  }
}
.progress__counter {
  position: absolute;
  top: 40%;
  transform: translateY(-40%);
  text-align: center;
  width: 100%;
  margin: 0;
  font-weight: bold;
  animation: progressCounter 100ms linear 1s forwards;
}
.progress__counter span {
  counter-increment: progress;
}
.progress__counter::after {
  content: counter(progress)"%";
  animation: progressCounterCompleted 1s linear 2s forwards;
}
@keyframes progressCounter {
  to {
    color: white;
  }
}
/* Chrome Only*/

@keyframes progressCounterCompleted {
  33% {
    content: "File(s)";
  }
  66% {
    content: "Uploaded";
  }
  100% {
    content: "Successfully!";
  }
}
代码语言:javascript
复制
<figure class="progress-container">
  <svg class="icon icon-bubble">
    <use xlink:href="#icon-bubble"></use>
  </svg>
  <figcaption class="progress__inner">
    <div class="progress__fill"></div>
    <p class="progress__counter"></p>
  </figcaption>
</figure>

<svg id="spritesheet">
  <symbol id="icon-bubble" viewBox="0 0 79.36 93.844">
    <title>Loading Bubble</title>
    <path id="bubble-cover" fill="currentColor" stroke="#000" d="M-10,-10 100,-10 100,100 -10,100 -10,-10  50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
  </symbol>
</svg>

票数 9
EN

Stack Overflow用户

发布于 2016-09-27 21:03:27

具有模式和y转换的SVG:

代码语言:javascript
复制
svg:hover pattern #fillshape {
  y: 0%;
}
pattern #fillshape {
  transition: y 1s;
  y: 100%;
}
代码语言:javascript
复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
    <pattern id="pattern1"
           x="0" y="0" width="79.36" height="93.844"
           patternUnits="userSpaceOnUse" >

      <rect id="fillshape" x="0" y="0" width="100%" height="200%" stroke="none" fill="purple" />

  </pattern>
  <path fill="url(#pattern1)" stroke="black" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</svg>

现在,这在火狐或边缘中不起作用。它不会将x和y识别为CSS属性...

这是一个在svg形状后面使用div的解决方案。这种解决方案的缺点是svg形状得到了一个背景,例如。如果只想要形状,则必须将形状的背景色与页面的背景色相匹配。

代码语言:javascript
复制
svg {
  position: relative;
} 
.spesial {
  width: 90px;
  height: 0px;
  display: inline-block;
  background-color: purple;
  margin-left: -100px;
  transition: height 1s;
}
svg:hover + .spesial {
  height: 100px;
}
代码语言:javascript
复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100" height="100" viewBox="0 0 75 90">
  <path stroke="black" fill="gray" d="M-10,-10 100,-10 100,100 -10,100 -10,-10  50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</svg>
<div class="spesial">
</div>

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38437325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档