【D3.js】地図上にオーバーレイしたSVG要素にドロップシャドウを付ける
昨日の記事でLeafletで作成した地図上にSVGをオーバーレイしましたが、地図タイルとの相性によっては上に重ねたSVG要素が分かりづらい場合があります。
そこで、SVGのfilter機能を用いてドロップシャドウエフェクトをかけることで、オーバーレイした要素を目立たせてみました。
比較
ノーマル
ドロップシャドウ付加
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
//Leaflet初期設定 var map = L.map('map').setView([39.702053 , 141.15448379999998], 5); var mapLink = '<a target="_blank" href="http://portal.cyberjapan.jp/help/termsofuse.html">国土地理院 地理院地図 標準地図</a>'; //Tile Map Serviceの指定 L.tileLayer( 'http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { attribution: '© ' + mapLink + ' Contributors', maxZoom: 18, }).addTo(map); // Leafletのoverlay paneにsvg要素を追加 var svg = d3.select(map.getPanes().overlayPane).append("svg"); //フィルター要素の追加 var filter = svg.append("defs").append('filter') .attr({ "id": "drop-shadow", "width": "150%", "height": "150%" }); //ガウス(ぼかし)フィルターを追加 filter.append('feGaussianBlur') .attr({ "in": "SourceAlpha", "result": "blur", "stdDeviation": "2" }); //平面移動フィルターを追加 filter.append('feOffset') .attr({ "result": "offsetBlur", "dx": 4, "dy": 4 }) //上記2つのエフェクトをブレンド(マージ)するフィルターを追加 filter.append('feBlend') .attr({ "in": "SourceGraphic", "in2": "offsetBlur", "mode": "normal" }); var g = svg.append("g").attr("class", "leaflet-zoom-hide"); d3.json("ken.geojson", function(geojson) { var transform = d3.geo.transform({point: projectPoint}); var path = d3.geo.path().projection(transform); d3_features = g.selectAll("path") .data(geojson.features) .enter() .append("path") .attr("filter", "url(#drop-shadow)"); //svg filterを指定 map.on("viewreset", update); update(); //SVG要素をleafletのマップレイヤーにフィットさせる function update() { var bounds = path.bounds(geojson); var topLeft = bounds[0]; var bottomRight = bounds[1]; svg .attr({ "width": bottomRight[0] - topLeft[0], "height": bottomRight[1] - topLeft[1] }) .style({ "left": topLeft[0] + "px", "top": topLeft[1] + "px" }) g .attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")"); // path要素(地形)追加 d3_features.attr("d", path) .attr({ "fill-opacity": 0.4, "fill": "green", "stroke": "red" }); } //位置→座標変換 function projectPoint(x, y) { var point = map.latLngToLayerPoint(new L.LatLng(y, x)); this.stream.point(point.x, point.y); } }) |