我可以沿SVG路径应用渐变吗?

ygo*_*goe 57 svg gradient path

我想在我的网站上放一个由脚本触发的简单加载指示器.它应该是一个简单的圆弧,它有一个渐变,并在用户等待时旋转.我还没有尝试动画部分,但现在却陷入了静态样式.这是我到目前为止所得到的:

<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"
        width="100" height="100">
        <defs>
            <linearGradient id="grad1">
                <stop offset="0%" stop-color="red"/>
                <stop offset="100%" stop-color="red" stop-opacity="0" />
            </linearGradient>
        </defs>
        <path d="M50 10  A40 40 0 1 0 90 50"
            stroke="url(#grad1)" stroke-width="10" fill="transparent"/>
    </svg>
Run Code Online (Sandbox Code Playgroud)

它绘制弧线,从顶部边缘逆时针到右边缘(270°),但梯度是错误的.而不是跟随路径使得开始(顶部边缘,0°)是不透明的并且末端(右边缘,270°)是透明的,所得到的弧形笔划的图像在屏幕空间中从左到右着色.

如何使渐变跟随我的弧形路径?

eri*_*oco 23

Mike Bostock想出了办法,虽然这并不容易:https: //bl.ocks.org/mbostock/4163057

基本上,这种技术用于getPointAtLength将笔划切割成许多短笔划,为每个笔划指定插值颜色停止,然后对这些停靠点之间的每个短笔划应用渐变.

祝你好运,如果你能接受挑战;)

  • 基本上这意味着“不”。Mike Bostock 所做的是完全自己创建渐变。您可以复制他的代码,并尝试修改它以满足您的需要,但就像已经说过的那样,它不会那么简单...... :) (2认同)
  • 这些正是我们现在迫切需要 SVG 标准更新的示例! (2认同)

Dos*_*nov 11

path{
 fill : url(#gradient)
}
Run Code Online (Sandbox Code Playgroud)
<svg width="660" height="220">
  <defs>
    <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%"   stop-color="#05a"/>
      <stop offset="100%" stop-color="#0a5"/>
    </linearGradient>
  </defs>
 <path d="M150 0 L75 200 L225 200 Z" />
</svg>
Run Code Online (Sandbox Code Playgroud)

  • 这似乎具有完全相同的从左到右而不是OP最初遇到的沿路径梯度问题 (5认同)

And*_*hiu 11

CSS 图像模块 - 第 4 级引入了conic-gradient。根据 MDN 的说法,除了 IE 之外,所有主流浏览器都支持它。

尽管从技术上讲,它不是沿着路径的渐变,但由于您的路径是圆形,因此可以通过以下方式实现所需的结果:

.loader {
  --size: 7.5rem;
  --stroke-size: .5rem;
  --diff: calc(calc(var(--size)/2) - var(--stroke-size));
  background-image: conic-gradient(transparent 25%, red);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  -webkit-mask:radial-gradient(circle var(--diff),transparent 98%,#fff 100%);
          mask:radial-gradient(circle var(--diff),transparent 98%,#fff 100%);
  animation: rotate 1.2s linear infinite;
  margin: 0 auto;
}
@keyframes rotate {
  from {
    transform: rotate(0);
  }
  to {
    transform: rotate(1turn);
  }
}
body {
  background: #f9fcfc url(https://picsum.photos/id/22/1323/880) 100% /cover;
  margin: 0;
  min-height: 100vh;
  padding-top: 2.5rem;
}
 * { box-sizing: border-box; }
Run Code Online (Sandbox Code Playgroud)
<div class="loader"></div>
Run Code Online (Sandbox Code Playgroud)

相关位是

background-image: conic-gradient(transparent 25%, red);
Run Code Online (Sandbox Code Playgroud)

注意:如果不明显,则 CSS 变量不是必需的,我只是想要一种以多种尺寸测试它的方法,而不必在多个位置修改值。
注意:遮盖内圆也可以使用 来实现<svg />。我怀疑它可能比mask有更好的浏览器支持。但这超出了这个问题的范围。

在发布时,我的示例似乎在最新的 Chrome、Firefox 和 Edge 中按预期工作。没有测试过 Safari。没想到它能在任何版本的 IE 中运行。


met*_*ion 10

这种类型的梯度在SVG中不易实现,参见SVG角度梯度.

此外,transparent它不是SVG中的有效颜色.您应该stop-opacity在此示例中说明:http://jsfiddle.net/WF2CS/

我担心最简单的解决方案可能是一系列具有不同不透明度的小弧线路径.


cer*_*eny 5

我也有这个问题,所以我创建了一个库来帮助创建遵循path. 如果您愿意,您可以在 Javascript 中单独使用它或与 D3.js 一起使用。该库 100% 基于 Mike Bostock 在第一个答案中引用的工作,但我已将 D3 作为必需的依赖项删除。

我还在 Medium 上写了一个简短的教程,描述了背景故事和用法。.