2012-11-17 76 views
0

我使用D3创建一个填充渐变的大对象,但对象越大,渐变变得越不平滑。下面是创建这种类型的伪像的代码的示例:长SVG对象中的渐变平滑

<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.27.1"> 
<script type="text/javascript"> 

var w = 4000, 
    h = 100, 
    m = 50; 

var svg = d3.select("body").append("svg:svg") 
    .attr("width", w) 
    .attr("height", h); 

var gradient = svg.append("svg:defs") 
    .append("svg:linearGradient") 
    .attr("id", "gradient") 
    .attr("x1", "0%") 
    .attr("y1", "0%") 
    .attr("x2", "100%") 
    .attr("y2", "0%") 
    .attr("spreadMethod", "pad"); 

for (i=0; i<m; i++) { 
    gradient.append("svg:stop") 
     .attr("offset", (i*100.0)/(m-1.0) + "%") 
     .attr("stop-color", "hsl(240,0%,"+(i%2)*100+"%)") 
     .attr("stop-opacity", 1); 
} 

svg.append("svg:rect") 
    .attr("width", w) 
    .attr("height", h) 
    .style("fill", "url(#gradient)"); 

    </script> 

是否有可能增加梯度一些SVG属性平滑?

回答

2

这是一个Chrome实现梯度的错误,它也发生在CSS渐变中。 http://code.google.com/p/chromium/issues/detail?id=41756。它可以在除Chrome以外的所有浏览器中正常工作。

幸运的,你的情况有一个变通方法:使用spreadMethod: reflect;,这将使你说明梯度在一个较小的区域,只是让浏览器重复:

var gradient = svg.append("svg:defs") 
    .append("svg:linearGradient") 
    .attr("id", "gradient") 
    .attr("x1", "0%") 
    .attr("y1", "0%") 
    .attr("x2", "2%") 
    .attr("y2", "0%") 
    .attr("spreadMethod", "reflect"); 

gradient.append("svg:stop") 
    .attr("offset", 0) 
    .attr("stop-color", "black") 
    .attr("stop-opacity", 1); 

gradient.append("svg:stop") 
    .attr("offset", 1) 
    .attr("stop-color", "white") 
    .attr("stop-opacity", 1); 

这也具有更好的性能。希望你的实际看起来有点相似!

这里你可以看到一个演示: http://jsfiddle.net/uKH4j/

+0

感谢您指出了Chrome浏览器的bug。在Firefox中,它效果很好。然而,在我的情况下,解决方法并不实际,因为不同的停止颜色应该具有不同的值 - 该数字应该表示测量中不同的密度(这就是为什么我使用hsl)。此外,将大数字分成多个数字不是一种选择。 –

+0

那么,解决这个问题的方法就是将rect分解成多个,使用多个渐变产生单个长渐变。尽管在两个矩形相遇的位置,您可能会获得渲染效果。 – meetamit