[英]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:
像这样:
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.