简体   繁体   English

svg 的动态角度线性梯度

[英]dynamically angle linear gradient of svg

I am dynamically adding linear gradients to each path within a circular diagram.我正在为圆形图中的每个路径动态添加线性渐变。 I want each gradient to split each path down the middle.我希望每个渐变将每条路径从中间分开。 Like so:像这样:

image alt

I know I am able to rotate the gradient using gradientTransform but the rotation is different depending on the path's location within the circular diagram.我知道我可以使用gradientTransform旋转gradientTransform但旋转是不同的,具体取决于圆形图中路径的位置。 How can I calculate the paths angle and draw the linear gradient accordingly?如何计算路径角度并相应地绘制线性渐变? I have also tried manipulating the x1, x2, y1, and y2 coordinates of the linear gradient, but I'm not sure how to manipulate them accordingly.我也尝试过操纵线性渐变的 x1、x2、y1 和 y2 坐标,但我不确定如何相应地操纵它们。

 let data = { name: "demo", children: [{ "ID": "001", "Games": "PS2", "children": [{ "ID": "001-1", "Games": "PS2", }] }, { "ID": "002", "Games": "PS2", "children": [{ "ID": "002-2", "Games": "PS2", }] }, { "ID": "003", "Games": "PS2", "children": [{ "ID": "003-1", "Games": "PS2", }] }, { "ID": "004", "Games": "PS2", "children": [{ "ID": "004-1", "Games": "PS2", }] }, { "ID": "005", "Games": "PS2", "children": [{ "ID": "005-5", "Games": "PS2", }] } ] } let width = 500; let height = 500; let radius = Math.min(width, height) / 2; let color = d3.scaleOrdinal(d3.schemeCategory20b); let g = d3.select('svg') .attr('width', width) .attr('height', height) .append('g') .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')'); // Data strucure let partition = d3.partition() .size([2 * Math.PI, radius]); // Find data root let root = d3.hierarchy(data) .sum(function(d) { return !d.children || d.children.length === 0 ? 2 : 0 }); // Size arcs partition(root); let arc = d3.arc() .startAngle(function(d) { return d.x0 }) .endAngle(function(d) { return d.x1 }) .innerRadius(function(d) { return d.y0 }) .outerRadius(function(d) { return d.y1 }); let svg = d3.select('svg') // Put it all together g.selectAll('path') .data(root.descendants()) .enter().append('path') .attr("stroke-width", "5") .each((d, i, m) => { let lg = svg.append("defs") .append("linearGradient") .attr("id", `gradient${d.data.ID}`) .attr("gradientTransform", `rotate(${0})`) .attr("x1", "0%") .attr("x2", "100%") .attr("y1", "0%") .attr("y2", "0%") lg.append("stop") .attr("offset", "50%") .attr("stop-color", "#188F6B") lg.append("stop") .attr("offset", "50%") .attr("stop-color", "#3BDBAB") }) .style("fill", (d) => { return `url(#gradient${d.data.ID})` }) .attr("display", function(d) { return d.depth ? null : "none"; }) .attr("d", arc) .style('stroke', '#fff')
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg></svg>

This is my solution: I'm using only one gradient and 2 paths.这是我的解决方案:我只使用一个渐变和 2 条路径。 The two one where the result is what you need.结果就是你需要的两个。 I'm grouping the 2 paths in a group with an id so that I can reuse it as many times as I need.我将 2 条路径与一个 id 分组到一个组中,以便我可以根据需要多次重复使用它。

This will simplify your code a lot.这将大大简化您的代码。 Please observe that I'm moving the style and all the attributes to the group since they are the same.请注意我正在将样式和所有属性移动到组中,因为它们是相同的。 You don't need to repeat yourself.你不需要重复自己。

Since the group is 1/5 of a circle this meant the spread angle of the group is 72º由于该组是圆的 1/5,这意味着该组的展开角为 72º

I'm reusing the group 4 times rotating the use element 1 72 degs, 2 72 degs, 3 72 degs and 4 72 degs.我重复使用该组 4 次,将使用元素旋转 1 72 度、2 72 度、3 72 度和 4 72 度。

Since the drawing is centered around the point {x:0,y:0} you don't need to add a rotation center.由于绘图以点 {x:0,y:0} 为中心,因此您无需添加旋转中心。

 <svg width="500" height="500" viewBox="-250 -250 500 500"> <g id="theG" style="fill: url(#gradient); stroke: rgb(255, 255, 255);" stroke-width="5"> <path d="M97.96420871541218,134.8361657291579A166.66666666666666,166.66666666666666,0,0,1,-97.96420871541217,134.8361657291579L-48.982104357706085,67.41808286457895A83.33333333333333,83.33333333333333,0,0,0,48.98210435770609,67.41808286457895Z" ></path> <path d="M146.9463130731183,202.25424859373686A250,250,0,0,1,-146.94631307311826,202.25424859373686L-97.96420871541217,134.8361657291579A166.66666666666666,166.66666666666666,0,0,0,97.96420871541218,134.8361657291579Z"></path> </g> <use xlink:href="#theG" transform="rotate(72)" /> <use xlink:href="#theG" transform="rotate(144)" /> <use xlink:href="#theG" transform="rotate(216)" /> <use xlink:href="#theG" transform="rotate(288)" /> <defs> <linearGradient id="gradient" gradientTransform="rotate(0)" x1="0%" x2="100%" y1="0%" y2="0%"> <stop offset="50%" stop-color="#188F6B"></stop> <stop offset="50%" stop-color="#3BDBAB"></stop> </linearGradient> </defs> </svg>

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

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