【D3.js】Google Mapにsvgを使ってマスクをかける
実は以前、ClipPathを使って似たようなことをやったことがあるのですが、Mask機能を使った方が綺麗に切り抜けたので掲載します。
地図上にオーバーレイしたSVGにマスクをかけるテクニックは、いろんなことに応用が利きそうですね。
サンプル
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 |
d3.json("../../_geodata/gunma_outline.geojson", function(json) { mapdraw(json); }); function mapdraw(json) { var feature = json.features; //Google Map 初期化 var map = new google.maps.Map(document.getElementById('map'), { zoom: 10, mapTypeId: google.maps.MapTypeId.TERRAIN, center: new google.maps.LatLng( 36.4894706, 139.00044819999994), }); //OverLayオブジェクトの作成 var overlay = new google.maps.OverlayView(); overlay.onAdd = function () { //オーバーレイ設定 var layer = d3.select(this.getPanes().overlayLayer).append("div").attr("class", "SvgOverlay"); var svg = layer.append("svg"); var defs = svg.append("defs"); var mask = defs.append("mask").attr("id", "mask"); //表示エリア指定マスク mask.append("rect").attr({ x:0, y:0, width:8000, height:8000, fill:"white" }); //実際に地図を隠すカバー var cover = svg.append("rect").attr({ x:0, y:0, width:8000, height:8000, fill:"gray" }); var overlayProjection = this.getProjection(); //Google Projection作成 var googleMapProjection = function (coordinates) { var googleCoordinates = new google.maps.LatLng(coordinates[1], coordinates[0]); var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(googleCoordinates); return [pixelCoordinates.x + 4000, pixelCoordinates.y + 4000]; } //パスジェネレーター作成 path = d3.geo.path().projection(googleMapProjection); //オーバーレイ描画イベント overlay.draw = function () { //マスクに地形のパスを追加し、非表示エリアとして指定 mask.selectAll("path") .data(feature) .attr("d", function(d){ return path(d) }) .enter() .append("svg:path") .attr({ "d": path, "fill": "black" }); //カバーにマスクを反映 cover.attr("mask", "url(#mask)"); }; }; //作成したSVGを地図にオーバーレイする overlay.setMap(map); }; |
※マスクの表示・非表示はSVGにかかっています。地図が表示される部分は、svg上の要素を非表示にした部分です。
混乱しがちなので注意が必要です。