SVG 进度条
SVG progress bar
我有一个需求,需要动态加载js文件,并通过SVG图标显示加载文件的进度。 SVG 图标将充当进度条,其中从下到上线性填充颜色。
这是codepen
<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.
#progressMove {
transition: .3s y;
}
#progressMove:hover {
y: 60%;
}
<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
PS: 我不想使用 SMIL 动画。
带有图案和 y 过渡的 SVG:
svg:hover pattern #fillshape {
y: 0%;
}
pattern #fillshape {
transition: y 1s;
y: 100%;
}
<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>
现在这在 Firefox 或 Edge 中不起作用。它无法将 x 和 y 识别为 CSS 属性...
这是一个在 svg 形状后面使用 div 的解决方案。
这个解决方案的缺点是 svg 形状有背景,例如。如果您只想要形状,则必须使形状的背景颜色与页面背景的颜色相匹配。
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;
}
<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>
CHROME/SAFARI 解决方案
使用CSS属性transform
和counter-increment
可以实现填充和数字递增。
代码片段
for (var i = 0; i < 100; i++) {
setTimeout(function() {
$(".progress-container p").append("<span>");
}, i * 20);
}
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)"%";
}
<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>
注:
如果我能提供更好的解决方案来涵盖浏览器支持,将会更新。
编辑:
根据 的回答,您还必须将背景颜色更改为其父项的颜色。
整个组件将是 figure
元素,遗憾的是 spritesheet 中的符号将仅用于提供路径和背景。
Note: jQuery removed in this version.
for (var i = 0; i < 100; i++) {
setTimeout(function() {
var progressCounter = document.querySelector(".progress__counter"),
number = document.createElement("span");
progressCounter.appendChild(number);
}, i * 20);
}
#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)"%";
}
<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
- 边缘
- 火狐 47
- IOS 10 个野生动物园
游乐场
for (var i = 0; i < 100; i++) {
setTimeout(function() {
var progressCounter = document.querySelector(".progress__counter"),
number = document.createElement("span");
progressCounter.appendChild(number);
}, i * 20);
}
#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!";
}
}
<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>
var prObject = document.getElementById("prObject"),
prDom = document.getElementById("progressMove"),
prValue = 0;
prObject.onmouseenter = function() {
prDom.setAttribute('class', 'prHover')
};
prObject.onmouseleave = function() {
prDom.removeAttribute('class')
};
/*prDom.setAttributeNS(null, 'y', '0');*/
var cTimer = setInterval(function() {
prValue += 20.6;
prDom.style.transform = "translateY(" + [100 - Math.min(prValue, 100)] + "%)";
if (prValue >= 100) {
clearInterval(cTimer);
}
}, 450);
#progressMove {
transition: transform 0.20s linear;
}
#progressMove.prHover {
transform: translateY(40%) !important;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<svg id="kenseoProgress" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<defs>
<path id="mypath" fill="white" 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 id="bubbleKenseo">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#mypath"></use>
</mask>
</defs>
<g x="0" y="0" width="79.36px" height="93.844px" mask="url(#bubbleKenseo)" height="100" stroke-width="0">
<rect id="progressMove" x="0" y="0" width="100%" height="100%" fill="blue" stroke="black" style="transform: translateY(100%);" />
</g>
<g id="prObject" x="0" y="0" width="79.36px" height="93.844px" height="100" fill-opacity="0" stroke="black" stroke-width="0.5px">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#mypath"></use>
</g>
</svg>
</body>
</html>
首先,您想使用 clip-path,或将 mask
填充设置为白色以获得 100% 不透明度:mask
用作灰度 Alpha 通道,红色填充颜色会导致不透明度变化。
至于描边,您想将其添加为不受剪裁影响的独立元素。 (您可能可以重复使用 defs
和 use
的路径,我只是将其复制粘贴到此处)
#progressMove {
transition: .3s y;
}
#progressMove:hover {
y: 60%;
}
<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>
我有一个需求,需要动态加载js文件,并通过SVG图标显示加载文件的进度。 SVG 图标将充当进度条,其中从下到上线性填充颜色。
这是codepen
<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.
#progressMove {
transition: .3s y;
}
#progressMove:hover {
y: 60%;
}
<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
PS: 我不想使用 SMIL 动画。
带有图案和 y 过渡的 SVG:
svg:hover pattern #fillshape {
y: 0%;
}
pattern #fillshape {
transition: y 1s;
y: 100%;
}
<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>
现在这在 Firefox 或 Edge 中不起作用。它无法将 x 和 y 识别为 CSS 属性...
这是一个在 svg 形状后面使用 div 的解决方案。 这个解决方案的缺点是 svg 形状有背景,例如。如果您只想要形状,则必须使形状的背景颜色与页面背景的颜色相匹配。
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;
}
<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>
CHROME/SAFARI 解决方案
使用CSS属性transform
和counter-increment
可以实现填充和数字递增。
代码片段
for (var i = 0; i < 100; i++) {
setTimeout(function() {
$(".progress-container p").append("<span>");
}, i * 20);
}
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)"%";
}
<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>
注:
如果我能提供更好的解决方案来涵盖浏览器支持,将会更新。
编辑:
根据
整个组件将是 figure
元素,遗憾的是 spritesheet 中的符号将仅用于提供路径和背景。
Note: jQuery removed in this version.
for (var i = 0; i < 100; i++) {
setTimeout(function() {
var progressCounter = document.querySelector(".progress__counter"),
number = document.createElement("span");
progressCounter.appendChild(number);
}, i * 20);
}
#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)"%";
}
<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
- 边缘
- 火狐 47
- IOS 10 个野生动物园
游乐场
for (var i = 0; i < 100; i++) {
setTimeout(function() {
var progressCounter = document.querySelector(".progress__counter"),
number = document.createElement("span");
progressCounter.appendChild(number);
}, i * 20);
}
#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!";
}
}
<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>
var prObject = document.getElementById("prObject"),
prDom = document.getElementById("progressMove"),
prValue = 0;
prObject.onmouseenter = function() {
prDom.setAttribute('class', 'prHover')
};
prObject.onmouseleave = function() {
prDom.removeAttribute('class')
};
/*prDom.setAttributeNS(null, 'y', '0');*/
var cTimer = setInterval(function() {
prValue += 20.6;
prDom.style.transform = "translateY(" + [100 - Math.min(prValue, 100)] + "%)";
if (prValue >= 100) {
clearInterval(cTimer);
}
}, 450);
#progressMove {
transition: transform 0.20s linear;
}
#progressMove.prHover {
transform: translateY(40%) !important;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<svg id="kenseoProgress" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<defs>
<path id="mypath" fill="white" 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 id="bubbleKenseo">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#mypath"></use>
</mask>
</defs>
<g x="0" y="0" width="79.36px" height="93.844px" mask="url(#bubbleKenseo)" height="100" stroke-width="0">
<rect id="progressMove" x="0" y="0" width="100%" height="100%" fill="blue" stroke="black" style="transform: translateY(100%);" />
</g>
<g id="prObject" x="0" y="0" width="79.36px" height="93.844px" height="100" fill-opacity="0" stroke="black" stroke-width="0.5px">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#mypath"></use>
</g>
</svg>
</body>
</html>
首先,您想使用 clip-path,或将 mask
填充设置为白色以获得 100% 不透明度:mask
用作灰度 Alpha 通道,红色填充颜色会导致不透明度变化。
至于描边,您想将其添加为不受剪裁影响的独立元素。 (您可能可以重复使用 defs
和 use
的路径,我只是将其复制粘贴到此处)
#progressMove {
transition: .3s y;
}
#progressMove:hover {
y: 60%;
}
<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>