【问题标题】:SVG filter doesn't work at allSVG过滤器根本不起作用
【发布时间】:2017-06-10 19:04:58
【问题描述】:

我正在尝试设置一个道尔顿过滤器(即模拟各种类型的色盲),但是,我用于此的 SVG 完全失败了。 Firefox 以背景颜色显示所有内容(虽然所有内容都被渲染,但绝对不可见),Chrome 正常显示页面。

由于我是从数据库中读取转换值,所以 SVG 是由这个 Perl 脚本生成的:

#!/usr/bin/perl -wT -I /srv/www1/cgi-lib

use strict;
use DBI;
use helpers qw(aindex);

my $dbname = 'DBI:mysql:<dbname>';
my $dbuser = '<dbuser>';
my $passwd = '<dbpass>';

my $p_http_ver = $ENV{'SERVER_PROTOCOL'};

my $p_debug = 0;

if($p_debug)
  {
  print "Content-Type: text/plain; charset=utf-8\n\n";
  }

sub get_params
  {
my ($l_script, $l_paramstr) = split(/\?/, $ENV{'REQUEST_URI'});

  return undef if(!defined $l_paramstr);

my @l_paramlist = split(/[&;]/, $l_paramstr);
my $l_this;
my %l_params = ( );

  foreach $l_this (@l_paramlist)
    {
my ($l_var, $l_value) = split(/=/, $l_this);

    next if(!defined $l_value);

    $l_value =~ s/\+/ /g;
    $l_value =~ s/%([0-9a-fA-F]{2})/pack("C", hex($1))/eg;

    $l_params{$l_var} = $l_value;
    }

  return \%l_params;
  }

my $params = get_params();
my %matrix = ( );
my @valid_modes = ( 'normal', 'protanopia', 'protanomaly', 'deuteranopia', 'deuteranomaly', 'tritanopia', 'tritanomaly', 'achromatopsia', 'achromatomaly' );

foreach (@valid_modes)
  {
# Fill in the normal matrix: Default for database failures!
  $matrix{$_} = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ];
  }

my $p_mode = ${$params}{'mode'};
$p_mode = 'normal' if(!defined $p_mode);
$p_mode = 'normal' if(aindex(@valid_modes, $p_mode) == -1);

print "Content-Type: image/svg+xml; charset=utf-8\n";
print "Expires: -60s\n";
print "Pragma: no-cache\n" if($p_http_ver eq 'HTTP/1.0');
print "Cache-Control: no-cache, no-store, must-revalidate\n" if($p_http_ver eq 'HTTP/1.1');

# Empty line to end the header section...
print "\n";

my $dbh = DBI->connect($dbname, $dbuser, $passwd, { PrintError => 0, AutoCommit => 0 });
if($dbh)
  {
my $l_sth;
my @l_row;
my $l_i;

  $l_sth = $dbh->prepare(qq{select * from dalton});
  $l_sth->execute();

  while(@l_row = $l_sth->fetchrow_array)
    {
    for($l_i = 0; $l_i < @l_row - 1; $l_i++)
      {
      ${$matrix{$l_row[0]}}[$l_i] = $l_row[$l_i + 1];
      }
    }  

  $l_sth->finish();

  $dbh->disconnect();
  }

print <<"EOT";
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg>
<defs>
EOT

my $filter;

foreach $filter (@valid_modes)
  {
my $l_i = 0;

  print "<filter id=\"$filter\">\n";
  print "<feColorMatrix type=\"matrix\" values=\"";
  for($l_i = 0; $l_i < @{$matrix{$filter}}; $l_i++)
    {
    print " " if($l_i);
    print ${$matrix{$filter}}[$l_i];
    if($l_i % 4 == 3)
      {
      print " 0.000";
      print "," if($l_i < @{$matrix{$filter}} - 1);
      }
    }
  print "\" />\n";
  print "</filter>\n";
  }

print <<"EOT";
</defs>
</svg>
EOT

以下用于将此过滤器附加到body元素:

body {
  filter: url('/cgi-bin/svg/dalton.pl#normal'); /* substitute any other ID for "normal" here if required */
  }

在浏览器中单独调用脚本时,我得到了文档结构(SVG 没有 CSS),并且在 validator.w3.org 上对其进行验证也没有发现任何错误。 但是,一旦我将它包含在我的 XHTML 文档的 CSS 中,事情就开始变得混乱了(不,-webkit-filter 也不能让这件事适用于 Chrome……)。

这里可能出了什么问题?现在我只见树木不见森林。

编辑:脚本产生以下输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg>
<defs>
<filter id="normal">
<feColorMatrix type="matrix" values="1.000 0.000 0.000 0.000 0.000, 0.000 1.000 0.000 0.000 0.000, 0.000 0.000 1.000 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="protanopia">
<feColorMatrix type="matrix" values="0.567 0.433 0.000 0.000 0.000, 0.558 0.442 0.000 0.000 0.000, 0.000 0.242 0.758 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="protanomaly">
<feColorMatrix type="matrix" values="0.817 0.183 0.000 0.000 0.000, 0.333 0.667 0.000 0.000 0.000, 0.000 0.125 0.875 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="deuteranopia">
<feColorMatrix type="matrix" values="0.625 0.375 0.000 0.000 0.000, 0.700 0.300 0.000 0.000 0.000, 0.000 0.300 0.700 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="deuteranomaly">
<feColorMatrix type="matrix" values="0.800 0.200 0.000 0.000 0.000, 0.258 0.742 0.000 0.000 0.000, 0.000 0.142 0.858 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="tritanopia">
<feColorMatrix type="matrix" values="0.950 0.050 0.000 0.000 0.000, 0.000 0.433 0.567 0.000 0.000, 0.000 0.475 0.525 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="tritanomaly">
<feColorMatrix type="matrix" values="0.967 0.033 0.000 0.000 0.000, 0.000 0.733 0.267 0.000 0.000, 0.000 0.183 0.817 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="achromatopsia">
<feColorMatrix type="matrix" values="0.299 0.587 0.114 0.000 0.000, 0.299 0.587 0.114 0.000 0.000, 0.299 0.587 0.114 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="achromatomaly">
<feColorMatrix type="matrix" values="0.618 0.320 0.062 0.000 0.000, 0.163 0.775 0.062 0.000 0.000, 0.163 0.320 0.516 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
</defs>
</svg>

【问题讨论】:

  • 我已附上。

标签: css svg svg-filters


【解决方案1】:

您的根 SVG 元素没有命名空间。你需要你的根元素是

<svg xmlns="http://www.w3.org/2000/svg">

【讨论】:

  • 谢谢。这实际上解决了它,现在至少 Chrome 的行为方式应该如此。 Firefox 仍然完全以背景颜色显示页面,但这似乎是该浏览器固有的问题。
  • 这链接到 Content-Security-Policy HTTP 标头(默认 src 拒绝),因此解决方法是删除标头 - 但该解决方案不能令人满意,除非我能找到一种方法专门为 Firefox 调整标题。此问题已为人所知,并且已经有待处理的错误报告。
猜你喜欢
  • 1970-01-01
  • 2016-05-20
  • 2015-10-02
  • 2018-05-28
  • 2016-07-02
  • 2021-04-24
  • 1970-01-01
  • 2023-04-11
  • 2018-07-23
相关资源
最近更新 更多