我一直在尝试创建一个圆形进度条,它的前面有一个箭头。
这是我目前所拥有的
HTML
<!-- Container -->
<ul class="progress">
<!-- Item -->
<li data-name="Item 1" data-percent="Item 1">
<svg viewBox="-10 -10 220 220">
<g fill="none" stroke-width="2" transform="translate(100,100)">
<path d="M 0,-100 A 100,100 0 0,1 86.6,-50" stroke="url(#cl1)"/>
<path d="M 86.6,-50 A 100,100 0 0,1 86.6,50" stroke="url(#cl2)"/>
<path d="M 86.6,50 A 100,100 0 0,1 0,100" stroke="url(#cl3)"/>
<path d="M 0,100 A 100,100 0 0,1 -86.6,50" stroke="url(#cl4)"/>
<path d="M -86.6,50 A 100,100 0 0,1 -86.6,-50" stroke="url(#cl5)"/>
<path d="M -86.6,-50 A 100,100 0 0,1 0,-100" stroke="url(#cl6)"/>
</g>
</svg>
<svg viewBox="-10 -10 220 220">
<path d="M200,100 C200,44.771525 155.228475,0 100,0 C44.771525,0 0,44.771525 0,100 C0,155.228475 44.771525,200 100,200 C155.228475" stroke-dashoffset="590"></path>
</svg>
</li>
</ul>
<!-- Defining Angle Gradient Colors -->
<svg width="0" height="0">
<defs>
<linearGradient id="cl1" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="1">
<stop stop-color="#18FFA9"/>
<stop offset="100%" stop-color="#18FFA9"/>
</linearGradient>
<linearGradient id="cl2" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1">
<stop stop-color="#18FFA9"/>
<stop offset="100%" stop-color="#4FC0EB"/>
</linearGradient>
<linearGradient id="cl3" gradientUnits="objectBoundingBox" x1="1" y1="0" x2="0" y2="1">
<stop stop-color="#4FC0EB"/>
<stop offset="100%" stop-color="#FD8AE6"/>
</linearGradient>
<linearGradient id="cl4" gradientUnits="objectBoundingBox" x1="1" y1="1" x2="0" y2="0">
<stop stop-color="#FD8AE6"/>
<stop offset="100%" stop-color="#4FC0EB"/>
</linearGradient>
<linearGradient id="cl5" gradientUnits="objectBoundingBox" x1="0" y1="1" x2="0" y2="0">
<stop stop-color="#4FC0EB"/>
<stop offset="100%" stop-color="#18FFA9"/>
</linearGradient>
<linearGradient id="cl6" gradientUnits="objectBoundingBox" x1="0" y1="1" x2="1" y2="0">
<stop stop-color="#18FFA9"/>
<stop offset="100%" stop-color="#18FFA9"/>
</linearGradient>
</defs>
</svg>
CSS
html,
body {
background-color: black;
color: white;
}
@keyframes load {
0% {
stroke-dashoffset: 0;
}
}
.progress {
position: relative;
display: inline-block;
padding: 0;
text-align: center;
}
.progress > li {
display: inline-block;
position: relative;
text-align: center;
font-size: 28px;
line-height: 34px;
}
.progress > li:after {
content: attr(data-percent);
position: absolute;
top: 40%;
left: 20%;
font-size: 28px;
text-align: center;
margin: auto;
width: 193px;
vertical-align: middle;
display: block;
text-transform: uppercase;
}
.progress svg {
width: 409px;
height: 409px;
}
.progress svg:nth-child(2) {
position: absolute;
left: 0;
top: 0;
transform: rotate(-90deg);
}
.progress svg:nth-child(2) path {
fill: none;
stroke-width: 25;
stroke-dasharray: 629;
stroke: black;
opacity: 0.9;
animation: load 1s;
}
https://jsfiddle.net/qr7cs40t/1
代码不是我写的,我是从我发现的一个例子中提取的,并做了一些样式修改。
使用 SVG 已成为一项挑战,因为我没有使用它的经验。我尝试查看有关如何使用 svg 添加箭头的多个教程,但没有成功。
我目前面临两个挑战:
箭头需要像这样的 https://fontawesome.com/icons/arrow-from-bottom?style=light 这样它与圆形进度条的宽度相同。
答案 0 :(得分:1)
从这个代码示例开始,你无法得到你想要的结果。
在动画开始时,可见的彩色弧线大部分被过度绘制的粗黑色描边弧线所隐藏。该弧具有一个笔划-dasharray,然后对其进行动画处理,以便该dasharray的未描边部分沿着曲线逐渐移动以显示下面的彩色弧。由于显示是由 dasharray 的移动创建的,因此无法调整标记的位置(您通常会这样做)以使其跟随显示边缘(至少使用 CSS)。>
您必须完全重构 SVG 并使用 JavaScript 或 SMIL 制作动画。
答案 1 :(得分:0)
这是我解决它的方法。我使用了一些我找到的基本代码并对其进行了修改以获得我需要的结果。
直接链接 https://codepen.io/lucky8919/pen/JjWXBYX
HTML
<div class="progress multicolor">
<span class="arrow"></span>
<span class="progress-left">
<span class="progress-bar"></span>
</span>
<span class="progress-right">
<span class="progress-bar"></span>
</span>
<div class="progress-value">90%</div>
</div>
CSS
html,
body {
background-color: black;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.progress {
width: 390px;
height: 390px;
line-height: 390px;
background: none;
margin: 0;
box-shadow: none;
position: relative;
}
.progress:after {
content: "";
width: 100%;
height: 100%;
border-radius: 50%;
border: 12px solid #000;
position: absolute;
top: 0;
left: 0;
}
.progress > span:not(.arrow) {
width: 50%;
height: 100%;
overflow: hidden;
position: absolute;
top: 0;
z-index: 1;
}
.progress > span.arrow {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9;
animation: rotate 2.7s linear forwards;
}
.progress > span.arrow:after {
content: "";
border-width: 8px;
border-style: solid;
border-color: transparent transparent transparent red;
position: absolute;
left: 198px;
top: -5px;
}
.progress .progress-left {
left: 1px;
}
.progress .progress-bar {
width: 100%;
height: 100%;
background: none;
border-width: 2px;
border-style: solid;
position: absolute;
top: 0;
}
.progress .progress-left .progress-bar {
left: 100%;
border-top-right-radius: 320px;
border-bottom-right-radius: 320px;
border-left: 0;
-webkit-transform-origin: center left;
transform-origin: center left;
}
.progress .progress-right {
right: 1px;
}
.progress .progress-right .progress-bar {
left: -100%;
border-top-left-radius: 320px;
border-bottom-left-radius: 320px;
border-right: 0;
-webkit-transform-origin: center right;
transform-origin: center right;
animation: loading-1 1.5s linear forwards;
}
.progress .progress-value {
position: absolute;
line-height: 390px;
width: 98%;
height: 98%;
border-radius: 50%;
top: 4px;
left: 4px;
z-index: 5;
background-color: #000;
font-family: inherit;
font-size: 28px;
text-transform: uppercase;
text-align: center;
color: white;
}
.progress.multicolor .progress-bar {
width: 100%;
height: 100%;
border: solid 2px transparent;
background-origin: border-box;
background-clip: content-box, border-box;
}
.progress.multicolor .progress-left .progress-bar {
background-image: linear-gradient(95.14deg, red 75%, blue 85%, green 100%);
}
.progress.multicolor .progress-right .progress-bar {
background-image: linear-gradient(95.14deg, green 0%, blue 25%, red 50%);
}
.progress.multicolor .progress-left .progress-bar {
animation: loading-2 1.2s linear forwards 1.5s;
}
@keyframes rotate {
from {transform:rotate(0deg)}
to {transform:rotate(324deg)}
}
@keyframes loading-1 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
}
@keyframes loading-2 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(144deg);
transform: rotate(144deg);
}
}