【问题标题】:CSS reference to SVG filter in separate element单独元素中对 SVG 过滤器的 CSS 引用
【发布时间】:2016-08-23 17:45:11
【问题描述】:

在使用 SVG 过滤器时,我遇到了从 CSS 引用 SVG 过滤器的问题。在某些情况下,应用过滤器将从页面中删除应用过滤器的元素。我认为可能有两个原因:

  1. 事实上我是使用D3JS 动态添加过滤器的;
  2. 事实上,我在 CSS 中引用过滤器,在单独的文件中定义。

为了测试这一点,我创建了一个 MWE 来演示该问题。对我来说,这在 Firefox 和 Chrome 中呈现,左框中没有任何内容,右框中有一个灰色圆圈(预期结果)。我认为这消除了原因 1。在我这样做之后,我尝试了:

  1. 使用url(.#filter-id) 引用,因此带有前导点。这并没有改变结果。
  2. defs 移动到与圆所在位置相同的svg 元素中。这是fixes 的问题。

我的问题:是否仍然可以以某种方式引用在单独的 SVG 元素中定义的过滤器?我非常希望在我的应用程序中这样做。我have read 外部文件有问题,但同一个文件中的不同元素肯定是可能的?

【问题讨论】:

  • 您是否尝试在 CSS 文件中写入#filter-id。该文件中没有 ID 为 filter-id 的元素,因为它在 HTML 文件中。
  • 嗯,是的,这就是我尝试url(.#filter-id) 的原因,我读到应该让它看起来在 HTML 文件中。至少对我来说没有。
  • 您应该找到一些更好的阅读材料:w3.org/TR/css3-values/#relative-urls 对于 CSS 样式表,基本 URL 是样式表本身的 URL,而不是样式源文档的基本 URL。
  • 感谢您的建议。我只是仔细检查了一遍,但是在 JSFiddle 上,无论如何都是内联的,所以 . 引用应该可以工作,对吧?

标签: css svg svg-filters


【解决方案1】:

我认为问题出在hidden类中的display:none,你可以用另一种方式隐藏,例如:

svg.hidden {
  height:0;
  margin:0;
  border:none;
}

var svg = d3.select('#container').append('svg'),
    defs = svg.append('defs'),
    dsFilter;

svg.attr('width', 400).attr('height', 200);

dsFilter = defs.append('filter').attr('id', 'grayscale-d3')
dsFilter.append('feColorMatrix')
  .attr('type', 'matrix')
  .attr('values',
        '0.3333 0.3333 0.3333 0 0 ' +
        '0.3333 0.3333 0.3333 0 0 ' +
        '0.3333 0.3333 0.3333 0 0 ' +
        '0      0      0      1 0')

svg.append('text').attr('x', 2).attr('y', 2).text('appended by D3');
svg.append('circle').attr('class', 'd3').attr('cx', 200).attr('cy', 120).attr('r', 60);
body {
  margin: 0;
  font-size: 0;
}

circle {
  fill: #bada55;
  stroke: #000;
  stroke-width: 1px;
}
circle.of {
  filter: url('#grayscale-of');
}
circle.d3 {
  filter: url('#grayscale-d3');
}

svg {
  display: inline-block;
  margin: 1rem 0 0 1rem;
  border: 1px solid #000;
}
svg.hidden {
  height:0;
  margin:0;  
  border:none;
}

text {
  dominant-baseline: text-before-edge;
  font-size: 1rem;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<svg class="hidden">
  <defs>
    <filter id="grayscale-of">
      <feColorMatrix values="0.3333 0.3333 0.3333 0 0
                             0.3333 0.3333 0.3333 0 0
                             0.3333 0.3333 0.3333 0 0
                             0      0      0      1 0"
                     type="matrix">
      </feColorMatrix>
    </filter>
  </defs>
</svg>
<div id="container">
  <svg width="400" height="200">
    <text x="2" y="2">already in page</text>
    <circle class="of" cx="200" cy="120" r="60" />
  </svg>
</div>

【讨论】:

  • 它必须是这样简单的东西!非常感谢,我想我不会想到这一点...Updated Fiddle,如果人们寻找它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2020-01-03
  • 1970-01-01
  • 2011-11-18
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多