如何使用svg剪切Leaflet geoJSON图层<clippath>

时间:2017-08-15 10:14:17

标签: javascript svg leaflet

根据the official tutorial,我现在可以加载并显示本地geoJSON文件中的所有多边形。我打算使用自定义大纲路径剪切新创建的SVG图层。我开始使用circle作为clipPath的子项,通过Leaflet的L.circle创建,以避免坐标投影。基于官方示例的主要代码如下:

// Create a circle outline
var clipcircle = new L.circle([34.5, -95.5], {radius: 300000, className: 'outline'}).addTo(map);
// Create <defs> and <clippath> elements using jquery
$('svg').prepend('<defs><clipPath id="myclip"></clipPath></defs>');
// Move the <path> element of clipcircle from <g> to <clipPath>
$('path.outline').appendTo('#myclip');
// Add CSS clip-path attribute to all svg groups
$('g').css('clip-path', 'url(#myclip)');
// load and show polygons from geoJSON
var geojson = L.geoJSON(statesData, {
        style: style,
        onEachFeature: onEachFeature
    }).addTo(map);
map.fitBounds(geojson.getBounds());

代码按预期工作,但clipPath无效。预计只会显示圆圈内的区域,但除圆圈外的所有多边形仍显示在页面上,如下图所示:

add the circle without moving

1 个答案:

答案 0 :(得分:1)

问题在于,当创建clipPath新元素时,jquery将元素名称小写为(stated in the specs),因为html标签不区分大小写(但好像clipPath确实区分大小写)

要解决此问题,您需要恢复到本机DOM操作并选择svg并使用 createElementNS 创建元素:

var svg = document.getElementsByTagName('svg')[0]

//Create a new element of clipPath
var clipPathChild = document.createElementNS('http://www.w3.org/2000/svg', "clipPath");

//set an ID (I went lazy and continued with jquery)
$(clipPathChild).attr('id', 'myclip')

//append new node to the svg
svg.appendChild(clipPathChild);

//the "outline" class was added previously to the geojson we want to use as mask 
// add the outline to clip the new node just created
$('path.outline').appendTo('#myclip');

//set the ID of the clip-path to the main feature to clip
$('path').attr('clip-path', 'url(#myclip)');

此解决方案对我有用,因为从理论上讲您的代码是正确的,但由于创建新元素时对jquery进行了简单的小写转换,因此该解决方案失败了