javascript - 有没有办法在没有可见边缘的情况下从不透明度 0 开始 svg 圆形描边填充?
问题描述
我有一个带有渐变笔划的 SVG 圆图。我的问题是我无法弄清楚如何从不透明度 0 开始不可见的渐变,并在最后使其不透明度为 1。我需要得到的是在下面的图像。
到目前为止,我在下面的代码段中拥有什么
/*graf animacie*/
.circle-chart__circle {
animation: circle-chart-fill 2s reverse; /* 1 */
transform: rotate(-90deg); /* 2, 3 */
transform-origin: center; /* 4 */
}
.circle-chart__circle--negative {
transform: rotate(-90deg) scale(1,-1); /* 1, 2, 3 */
}
.circle-chart__info {
animation: circle-chart-appear 2s forwards;
opacity: 0;
transform: translateY(0.3em);
}
@keyframes circle-chart-fill {
to { stroke-dasharray: 0 100; }
}
@keyframes circle-chart-appear {
to {
opacity: 1;
transform: translateY(0);
}
}
.grid {
display: grid;
grid-column-gap: 1em;
grid-row-gap: 1em;
grid-template-columns: repeat(1, 1fr);
}
@media (min-width: 31em) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
<div style="margin: auto; display: contents; text-align: center;">
<section>
<svg class="circle-chart" viewbox="0 0 33.83098862 33.83098862" width="150" height="200" xmlns="http://www.w3.org/2000/svg">
<circle class="circle-chart__background" stroke="#efefef" stroke-width="2" fill="none" cx="16.91549431" cy="16.91549431" r="15.91549431" />
<circle class="circle-chart__background" stroke="white" stroke-width="2" fill="none" cx="16.91549431" cy="16.91549431" r="15.91549431" />
<circle class="circle-chart__circle circle-chart__circle--negative" stroke="url(#gradient)" stroke-width="2" stroke-dasharray="90,100" stroke-linecap="" fill="none" cx="16.91549431" cy="16.91549431" r="15.91549431" />
<g class="circle-chart__info">
<text class="circle-chart__percent" x="16.91549431" y="15.5" alignment-baseline="central" text-anchor="middle" font-size="8">DEMO</text>
</g>
<defs>
<linearGradient id="gradient" x1="1" y1="1" x2="0" y2="0">
<stop offset="0.01" stop-color="#fdfafa"></stop>
<stop offset="0.20" style="stop-color:#e5b4b6"/>
<stop offset="0.80" style="stop-color:#c2545a"/>
<stop offset="1" stop-color="#AE1515"></stop>
</linearGradient>
</defs>
</svg>
</section>
</div>
在此先感谢您的帮助。
解决方案
你在这里需要的是一个“圆锥渐变”。不幸的是,SVG 本身不支持圆锥渐变。它们在 CSS 中受支持,但您还不能将 CSS 渐变应用于 SVG 元素。
选项1(不是真正的选项:)
您可以将圆锥渐变应用于 HTML 元素,然后使用 SVG 蒙版对其进行遮罩以产生最终效果。不幸的是,使用 SVG 掩码屏蔽 HTML 元素,目前仅适用于 Firefox。
演示(仅限火狐)
.chart-container {
/* positioned parent is required in order for us to stack the children on top of each other */
position: relative;
}
.chart-container .conic {
width: 200px;
height: 200px;
background: conic-gradient(rgba(176, 37, 44, 1) 34deg, rgba(176, 37, 44, 0) 326deg);
mask: url(#div-mask);
}
.chart-container svg {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.div-mask-path {
stroke-dasharray: 100 100;
animation: circle-chart-fill 2s forwards;
}
@keyframes circle-chart-fill {
from { stroke-dashoffset: 100; }
to { stroke-dashoffset: 0; }
}
<div class="chart-container">
<div class="conic"/>
<svg viewBox="0 0 100 100">
<mask id="div-mask" maskContentUnits="objectBoundingBox">
<path class="div-mask-path"
d="M 0.2706,0.1723
A 0.40,0.40 0 0 0 0.5,0.90
A 0.40,0.40 0 0 0 0.7294,0.1723"
fill="none" stroke="white" stroke-width="0.12"
pathLength="100"/>
</mask>
</svg>
</div>
选项 2
如果您知道您的页面背景颜色将是什么。您可以使用与上述类似的技术,但不是屏蔽 HTML 元素,而是用一个 SVG 元素覆盖它,并在其中切出一个孔。
演示(应该适用于所有浏览器)
.chart-container {
/* positioned parent is required in order for us to stack the children on top of each other */
position: relative;
}
.chart-container .conic {
width: 200px;
height: 200px;
background: conic-gradient(rgba(176, 37, 44, 1) 34deg, rgba(176, 37, 44, 0) 326deg);
}
.chart-container svg {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.div-mask-path {
stroke-dasharray: 2.025 2.025;
animation: circle-chart-fill 2s forwards;
}
@keyframes circle-chart-fill {
from { stroke-dashoffset: 2.025; }
to { stroke-dashoffset: 0; }
}
<div class="chart-container">
<div class="conic"/>
<svg viewBox="0 0 100 100">
<defs>
<mask id="div-mask" maskContentUnits="objectBoundingBox">
<!-- mask is mostly solid (white parts) -->
<rect width="1" height="1" fill="white"/>
<!-- but has a hole cut in it (black path) -->
<path class="div-mask-path"
d="M 0.2706,0.1723
A 0.40,0.40 0 0 0 0.5,0.90
A 0.40,0.40 0 0 0 0.7294,0.1723"
fill="none" stroke="black" stroke-width="0.12"/>
</mask>
</defs>
<!-- use a white rectangle (matches page background)
to cover the <div> with the conic gradient -->
<rect width="100" height="100" fill="white" mask="url(#div-mask)"/>
</svg>
</div>
选项 3
而不是使用<div>
具有圆锥渐变的元素。创建包含圆锥渐变的位图图像;将其包含在 SVG 中;而是掩盖该图像。
演示(应该适用于所有浏览器)
请注意,我在这里搞砸了,并在这里创建了一个纯白色到红色的 PNG,而不是您想要的透明到红色的 PNG。这只是我的一个错误。我现在懒得重新创建它了。我会把它留给你:)
svg {
width: 200px;
}
.div-mask-path {
stroke-dasharray: 2.025 2.025;
animation: circle-chart-fill 2s forwards;
}
@keyframes circle-chart-fill {
from { stroke-dashoffset: 2.025; }
to { stroke-dashoffset: 0; }
}
<svg viewBox="0 0 100 100">
<defs>
<mask id="div-mask" maskContentUnits="objectBoundingBox">
<path class="div-mask-path"
d="M 0.2706,0.1723
A 0.40,0.40 0 0 0 0.5,0.90
A 0.40,0.40 0 0 0 0.7294,0.1723"
fill="none" stroke="white" stroke-width="0.12"/>
</mask>
</defs>
<image xlink:href="https://i.imgur.com/cqhjI45.png"
width="100" height="100"
mask="url(#div-mask)"/>
</svg>
选项 4
通过将一系列 SVG 元素排列成一个圆圈来创建渐变。从一个透明的开始,然后将颜色插入到终点。然后使用与选项 3 相同的技术屏蔽该组元素。这将起作用,但会产生更大的 SVG,因为您将添加多达 256 个额外元素来创建该渐变序列。
(此处不演示)
推荐阅读
- docker - 为什么 Dockerfile 中不使用暴露端口?
- javascript - TypeError:无法读取引导程序中未定义的属性“状态”
- python - 网络摄像头流上的时间叠加
- json - 如何从 django 请求中获取分钟/小时/秒?
- java - 如何为 Java 中的 String 对象生成 hashCode()?
- .htaccess - 将所有重定向到 ssl,管理面板除外
- php - 登录并在php中注册没有响应
- python - 如何通过生成两个时间段之间的日期范围来填充数据框中缺失的日期值
- json - 如何从 iOS Swift 中的 JSON 响应中获取数据?
- kubernetes - Helm - Configmap - 仅替换文件的内容而不是文件名