我正在尝试用渐变背景颜色从红色到黄色到绿色制作一个SVG,在SVG里面我有2个多边形(现在因为那里会更多)我希望会掩盖SVG的背景。我尝试了以下代码:
<svg height="500" width="500">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:rgb(34,177,76);stop-opacity:1" />
<stop offset="50%" style="stop-color:rgb(255,242,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(237,28,36);stop-opacity:1" />
</linearGradient>
</defs>
<polygon points="0, 0, 100, 0, 100, 100, 0, 100" fill="url(#grad1)">
<polygon points="100, 100, 150, 250, 300, 350, 150, 400, 100, 300" fill="url(#grad1)" >
</svg>
如何将背景应用于SVG并让多边形根据其位置显示背景的一部分?
更新
我更新了我的代码(是的,它需要一些工作),以获得具有统一背景的路径,并且还有透明多边形,以防您希望添加onclick事件。
<?php
//Array with the different sections and their coordinates
$body['item1'] = array(array(0, 0), array(100, 0), array(100, 100), array(0, 100));
$body['item2'] = array(array(100, 100), array(150, 250), array(300, 350), array(150, 300), array(100, 300));
$body['item3'] = array(array(300, 50), array(300, 350), array(200, 350), array(200, 50));
?>
<svg x="0px" y="0px" height="500px" width="500px">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0" style="stop-color:rgb(34,177,76);" />
<stop offset="50%" style="stop-color:rgb(255,242,0);" />
<stop offset="100%" style="stop-color:rgb(237,28,36);" />
</linearGradient>
</defs>
<g id="singlePath_correctGradient" fill="url(#gradient)">
<?php
$polygon = '';
echo '<path d="';
foreach ($body as $key => $values) {
$polygon .= '<polygon points="';
$a = 1;
foreach ($values as $coord) {
echo $a == 1 ? ' M ' . $coord[0] . ', ' . $coord[1] : '';
echo $a == 2 ? ' L ' . $coord[0] . ', ' . $coord[1] : '';
echo $a > 2 ? ', ' . $coord[0] . ', ' . $coord[1] : '';
$polygon .= ($a == 1 ? '' : ', ') . $coord[0] . ', ' . $coord[1];
$a++;
}
$polygon .= '" onclick="alert(\'' . $key . '\')" fill-opacity="0"/>';
}
echo '"></path>';
echo $polygon;
?>
</g>
</svg>
答案 0 :(得分:1)
Change your gradientUnits to "userSpaceOnUse" - that way the gradient is defined in the SVG box space, not the filled unit. Easy. (and please, close your elements!! - SVG is XML)
<svg x="0px" y="0px" height="500px" width="500px" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad1" x1="0" y1="0" x2="300" y2="350" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(34,177,76);" />
<stop offset="50%" style="stop-color:rgb(255,242,0);" />
<stop offset="100%" style="stop-color:rgb(237,28,36);" />
</linearGradient>
</defs>
<polygon points="0, 0, 100, 0, 100, 100, 0, 100" fill="url(#grad1)"/>
<polygon points="100, 100, 150, 250, 300, 350, 150, 400, 100, 300" fill="url(#grad1)" />
</svg>
答案 1 :(得分:0)
更新:我现在在下面显示两个代码段。第一个(原始)代码段显示了手动解决方案。第二个(较新的)代码段显示了使用JavaScript的编程解决方案。
将多边形转换为路径是否正常?如果是这样,您可以将多个多边形组合成一个路径,然后将渐变应用于整个事物。在下面的第一个代码段中,我展示了三个组:
基本上,要将多边形转换为路径,请将points
属性更改为d
属性。然后,在d
值字符串中,在开头放置一个M
(用于“MoveTo”),在前两个数字后放置一个L
(用于“LineTo”)。在路径中间放置一个M
就可以告诉程序“抬起笔,无需绘制任何东西,将其移动到这个新位置并继续绘制”,有效地允许您绘制多个“形状”一条路。
<svg height="500" width="500">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:rgb(34,177,76);stop-opacity:1" />
<stop offset="50%" style="stop-color:rgb(255,242,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(237,28,36);stop-opacity:1" />
</linearGradient>
</defs>
<g id="twoPolygons_incorrectGradient" fill="url(#grad1)" transform="scale(0.5) translate(0,0)">
<polygon points="0, 0 100, 0, 100, 100, 0, 100"></polygon>
<polygon points="100, 100 150, 250, 300, 350, 150, 400, 100, 300"></polygon>
</g>
<g id="twoPaths_incorrectGradient" fill="url(#grad1)" transform="scale(0.5) translate(300,0)">
<path d="M 0, 0 L 100, 0, 100, 100, 0, 100"></path>
<path d="M 100, 100 L 150, 250, 300, 350, 150, 400, 100, 300"></path>
</g>
<g id="singlePath_correctGradient" fill="url(#grad1)" transform="scale(0.5) translate(600,0)">
<path d="M 0, 0 L 100, 0, 100, 100, 0, 100
M 100, 100 L 150, 250, 300, 350, 150, 400, 100, 300"></path>
</g>
<g>
<text x="0" y="70">wrong</text>
<text x="150" y="70">wrong</text>
<text x="300" y="70">right</text>
</g>
</svg>
我已手动完成上述转换。但是,这种类型的转换也可以通过编程方式完成,例如,使用JavaScript,我在下面的第二个片段中完成了。基本上,这会做到以下几点:
points
属性值字符串d
属性下面的示例最初显示了7个多边形,其中相同的渐变应用于每个单独的形状。请注意,最后一个多边形只是一个点,因此是不可见的,用虚线圆圈表示。
单击“组合...”按钮后,多边形2和3将合并为一条路径,多边形4和5以及多边形6和7也会合并。现在将相同的渐变应用于每个组合路径。请注意路径组合如何影响渐变颜色的位置。
请注意,我编写的实用程序函数就像向数组中添加更多的多边形ID一样简单,以便将两个以上的多边形组合在一起。
var xmlns = "http://www.w3.org/2000/svg";
var combine = function(polygonIds, newPathId) {
var $newPath = $(document.createElementNS(xmlns, "path"));
// jQuery does not work here, e.g. var $newPath = $("<path>", {id: newPathId});
$newPath.attr("id", newPathId);
$("svg").append($newPath);
var dStr = "";
polygonIds.forEach(function(polygonId, idx, arr) {
var $polygon = $("#" + polygonId);
var ptsStr = $polygon.attr("points");
dStr += "M " + ptsStr.replace(/, *| +/g, " ").trim().replace(/^([^ ]+ [^ ]+ )(.*)/, "$1L $2 $1");
});
dStr += "Z";
$newPath.attr("d", dStr);
};
$("button#combine").click(function() {
combine(["shape2", "shape3"], "path2and3");
combine(["shape4", "shape5"], "path4and5");
combine(["shape6", "shape7"], "path6and7");
$("#path2and3").attr("fill", "url(#grad1)");
$("#path4and5").attr("fill", "url(#grad1)");
$("#path6and7").attr("fill", "url(#grad1)");
$("#labels").remove().appendTo($("svg"));
});
$("button#delete").click(function() {
$("path").remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Best viewed on "Full Page"</p>
<p>The "Combine..." button will combine polygons 2 and 3, polygons 4 and 5, and polygons 6 and 7. Polygon 7 is a single dot and is thus essentially invisible. The same gradient is applied to each individual polygon as well as to each of the new paths.</p>
<div>
<button id="combine">Combine polygons into paths</button>
<button id="delete" >Delete new paths </button>
</div>
<svg height="500" width="500">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:rgb(34,177,76);stop-opacity:1" />
<stop offset="50%" style="stop-color:rgb(255,242,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(237,28,36);stop-opacity:1" />
</linearGradient>
</defs>
<g fill="url(#grad1)" transform="scale(1) translate(0,0)">
<polygon id="shape1" points=" 30, 100 60, 160 30, 220 0, 160"></polygon>
<polygon id="shape2" points="100, 0 120, 0 110, 120" ></polygon>
<polygon id="shape3" points="130, 100 160, 160 130, 220 100, 160"></polygon>
<polygon id="shape4" points="230, 100 260, 160 230, 220 200, 160"></polygon>
<polygon id="shape5" points="210, 200 220, 320 200, 320" ></polygon>
<polygon id="shape6" points="330, 100 360, 160 330, 220 300, 160"></polygon>
<polygon id="shape7" points="330, 320" ></polygon>
</g>
<circle cx="330" cy="320" r="10" fill="none" stroke="black" stroke-dasharray="3 3"></circle>
<g id="labels" font-family="Verdana" font-size="18">
<text x=" 24" y="165">1</text>
<text x="104" y=" 20">2</text>
<text x="124" y="165">3</text>
<text x="224" y="165">4</text>
<text x="204" y="310">5</text>
<text x="324" y="165">6</text>
<text x="324" y="305">7</text>
</g>
</svg>