为什么我的渐变颜色过渡无效?

时间:2019-01-31 23:08:37

标签: javascript d3.js svg

我正在尝试更改rect元素的填充颜色。

var linearGradient = svg.append("defs")
    .append("linearGradient")
    .attr("id", "linear-gradient-"+key);
...
svg.append("rect")
    .attr("id","color-filler")
    .attr("width", width)
    .attr("height", height)
    .style("fill", "url(#linear-gradient-old)");

单击单选按钮时,它会调用一个函数来更改填充颜色。

svg.select("#color-filler")
    .transition().duration(900)
    .style("fill", "url(#linear-gradient-new)");

它确实改变了颜色,但是完全没有过渡。有其他方法可以尝试吗?

1 个答案:

答案 0 :(得分:3)

D3转换在转换值时使用d3的插值器。使用的插补器取决于值的性质:

  
      
  1. 如果值是数字,请使用interpolateNumber。
  2.   
  3. 如果值是颜色或可强制转换为颜色的字符串,请使用interpolateRgb。
  4.   
  5. 使用interpolateString。 (from the docs
  6.   

您正在提供一个字符串,字符串插值器将“查找嵌入在a和b中的数字,其中每个数字都是JavaScript可以理解的形式”(docs)。然后插入每个值中的匹配数字。

即使可以插入起始字符串和结束字符串之间的空格-您也要插入字符串,而不是字符串所引用的引用,当然也就是要插入的元素的属性。

相反,您可以插值渐变的属性,而不是使用该渐变的元素:

var svg = d3.select("svg");

var gradient = svg.append("defs")
    .append("linearGradient")
    .attr("id", "linear-gradient");
    
var stops = gradient.selectAll("stop")
    .data([{offset:"0%",color1:"steelblue",color2:"yellow"},
           {"offset":"100%",color1:"crimson",color2:"steelblue"}])
    .enter()
    .append("stop")
    .attr("offset",function(d) { return d.offset; })
    .attr("stop-color", function(d) { return d.color1; })

var rect = svg.append("rect")
    .attr("id","color-filler")
    .attr("width", 100)
    .attr("height", 100)
    .style("fill", "url(#linear-gradient)");
    
stops.transition()
  .attr("stop-color", function(d) { return d.color2; })
  .duration(2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

一个不太吸引人的替代方法是构建一个将在参考梯度之间转换的插值器。如果每个梯度的停靠点数不相等,或者旋转角度不同,这将涉及更多的问题,并且还需要额外的考虑。这也将需要使用临时元素或修改现有的梯度