简体   繁体   English

为什么渐变色的过渡不起作用?

[英]Why doesn't my transition for gradient color work?

I'm trying to change fill color of a rect element. 我正在尝试更改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)");

When clicking a radio button, it calls a function to change the fill color. 单击单选按钮时,它会调用一个函数来更改填充颜色。

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

It did change the color, but there were no transition at all. 它确实改变了颜色,但根本没有转变。 Is there any alternative way to try this? 有没有其他方法可以试试这个?

D3 transitions use d3's interpolators when transitioning a value. 转换值时,D3转换使用d3的插值器。 The interpolator used depends on the nature of the value: 使用的插值器取决于值的性质:

  1. If value is a number, use interpolateNumber. 如果value是数字,请使用interpolateNumber。
  2. If value is a color or a string coercible to a color, use interpolateRgb. 如果value是颜色或可强制颜色的字符串,请使用interpolateRgb。
  3. Use interpolateString. 使用interpolateString。 ( from the docs ) 来自文档

You are supplying a string, the string interpolator will "find numbers embedded in a and b, where each number is of the form understood by JavaScript" ( docs ). 您正在提供一个字符串,字符串插值器将“找到嵌入在a和b中的数字,其中每个数字都是JavaScript理解的形式”( docs )。 Matching numbers in each value are then interpolated. 然后对每个值中的匹配数进行插值。

Even if the space between the start and end strings could be interpolated - you'd be interpolating the string, not the reference that the string refers to, and certainly not the properties of the referenced elements. 即使可以插入起始字符串和结束字符串之间的空格 - 您要插入字符串,而不是字符串引用的引用,当然也不是引用元素的属性。

Instead, you could interpolate a gradient's properties rather than the element using that gradient: 相反,您可以插入渐变的属性而不是使用该渐变的元素:

 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> 

A much less appealing alternative would be to build an interpolator that would transition between the referenced gradients. 一个不太吸引人的替代方案是构建一个在参考梯度之间转换的插值器。 This would be much more involved and would require extra considerations if the number of stops was unequal for each gradient, or if the rotation was different, etc. It would also require the use of a temporary element or the modification of existing gradient(s). 这将涉及更多,如果每个梯度的停止次数不相等,或者旋转不同等,则需要额外考虑。还需要使用临时元素或修改现有梯度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM