You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在D3 SVG三角形中实现三顶点不同颜色的渐变填充?

实现SVG三角形三色顶点渐变填充

问题分析

你尝试的多径向渐变叠加不可行,因为单个SVG元素只能设置一个填充属性,后续的style('fill')会直接覆盖之前的配置。要实现三个顶点分别为不同颜色的渐变填充,SVG原生没有直接的"三角形渐变"属性,但可以通过两种方式实现:


方案1:叠加线性渐变(兼容性好)

核心思路是创建三个重叠的三角形,每个使用从一个顶点到对边的线性渐变(顶点颜色过渡到透明),叠加后即可呈现三色顶点的渐变效果。

修改后的D3代码:

var svgDefs = svg.append('defs');

// 顶部顶点(黑色)到底边的渐变
var gradientTop = svgDefs.append("linearGradient")
    .attr("id", "gradientTop")
    .attr("x1", "50%")
    .attr("y1", "0%")
    .attr("x2", "50%")
    .attr("y2", "100%");

gradientTop.append("stop")
    .attr("offset", "0%")
    .attr("stop-color", "black")
    .attr("stop-opacity", 1);

gradientTop.append("stop")
    .attr("offset", "100%")
    .attr("stop-color", "black")
    .attr("stop-opacity", 0);

// 左下角(蓝色)到对边的渐变
var gradientLeft = svgDefs.append("linearGradient")
    .attr("id", "gradientLeft")
    .attr("x1", "0%")
    .attr("y1", "100%")
    .attr("x2", "100%")
    .attr("y2", "0%");

gradientLeft.append("stop")
    .attr("offset", "0%")
    .attr("stop-color", "blue")
    .attr("stop-opacity", 1);

gradientLeft.append("stop")
    .attr("offset", "100%")
    .attr("stop-color", "blue")
    .attr("stop-opacity", 0);

// 右下角(红色)到对边的渐变
var gradientRight = svgDefs.append("linearGradient")
    .attr("id", "gradientRight")
    .attr("x1", "100%")
    .attr("y1", "100%")
    .attr("x2", "0%")
    .attr("y2", "0%");

gradientRight.append("stop")
    .attr("offset", "0%")
    .attr("stop-color", "red")
    .attr("stop-opacity", 1);

gradientRight.append("stop")
    .attr("offset", "100%")
    .attr("stop-color", "red")
    .attr("stop-opacity", 0);

var trianglePoints = [[xScale(0), yScale(0)], [xScale(1), yScale(0)], [xScale(0.5), yScale(1)]];

// 叠加三个三角形,每个应用一个渐变
svg.append('polygon')
    .attr('points', trianglePoints)
    .style('fill', "url(#gradientTop)");

svg.append('polygon')
    .attr('points', trianglePoints)
    .style('fill', "url(#gradientLeft)");

svg.append('polygon')
    .attr('points', trianglePoints)
    .style('fill', "url(#gradientRight)");

方案2:使用SVG 2 Mesh Gradient(简洁但兼容性有限)

SVG 2的<meshGradient>支持直接定义三角形顶点的颜色,完美匹配需求,但目前仅Chrome等现代浏览器支持。

示例代码:

var svgDefs = svg.append('defs');

var meshGradient = svgDefs.append("meshGradient")
    .attr("id", "meshGradient")
    .attr("gradientUnits", "userSpaceOnUse")
    .attr("x1", xScale(0))
    .attr("y1", yScale(0))
    .attr("x2", xScale(1))
    .attr("y2", yScale(0))
    .attr("x3", xScale(0.5))
    .attr("y3", yScale(1));

meshGradient.append("meshPatch")
    .attr("points", "0,0 1,0 0.5,1")
    .append("stop")
    .attr("stop-color", "black")
    .attr("offset", "0,0");

meshGradient.append("stop")
    .attr("stop-color", "blue")
    .attr("offset", "1,0");

meshGradient.append("stop")
    .attr("stop-color", "red")
    .attr("offset", "0.5,1");

var trianglePoints = [[xScale(0), yScale(0)], [xScale(1), yScale(0)], [xScale(0.5), yScale(1)]];

svg.append('polygon')
    .attr('points', trianglePoints)
    .style('fill', "url(#meshGradient)");

关键注意事项

  • 将polyline替换为polygon:polyline是开放路径,填充时可能出现不符合预期的效果,polygon作为闭合图形更适合三角形场景。
  • 方案1兼容性覆盖所有主流浏览器;方案2仅在支持SVG 2特性的浏览器中生效。

内容的提问来源于stack exchange,提问作者Jan Paszka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:50:00