From fbe9cf3afda248c68439fc920a58f42fafbe635b Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 29 Oct 2016 21:50:30 -0400 Subject: [PATCH] Clip polygons and clippaths to padded viewport (closes #3529) --- modules/svg/areas.js | 2 -- modules/svg/path.js | 22 +++++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/modules/svg/areas.js b/modules/svg/areas.js index afcefb3f7..d0631d4b3 100644 --- a/modules/svg/areas.js +++ b/modules/svg/areas.js @@ -109,8 +109,6 @@ export function svgAreas(projection, context) { .filter(filter) .data(function(layer) { return data[layer]; }, osmEntity.key); - // Remove exiting areas first, so they aren't included in the `fills` - // array used for sorting below (https://github.com/openstreetmap/iD/issues/1903). paths.exit() .remove(); diff --git a/modules/svg/path.js b/modules/svg/path.js index c79fa48fd..1d347b350 100644 --- a/modules/svg/path.js +++ b/modules/svg/path.js @@ -1,11 +1,27 @@ import * as d3 from 'd3'; -export function svgPath(projection, graph, polygon) { +export function svgPath(projection, graph, isArea) { + + // Explanation of magic numbers: + // "padding" here allows space for strokes to extend beyond the viewport, + // so that the stroke isn't drawn along the edge of the viewport when + // the shape is clipped. + // + // When drawing lines, pad viewport by 5px. + // When drawing areas, pad viewport by 65px in each direction to allow + // for 60px area fill stroke (see ".fill-partial path.fill" css rule) + var cache = {}, - clip = d3.geoIdentity().clipExtent(projection.clipExtent()).stream, + padding = isArea ? 65 : 5, + viewport = projection.clipExtent(), + paddedExtent = [ + [viewport[0][0] - padding, viewport[0][1] - padding], + [viewport[1][0] + padding, viewport[1][1] + padding] + ], + clip = d3.geoIdentity().clipExtent(paddedExtent).stream, project = projection.stream, path = d3.geoPath() - .projection({stream: function(output) { return polygon ? project(output) : project(clip(output)); }}); + .projection({stream: function(output) { return project(clip(output)); }}); return function(entity) { if (entity.id in cache) {