diff --git a/CHANGELOG.md b/CHANGELOG.md index 55001fb98..621ced9da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ _Breaking developer changes, which may affect downstream projects or sites that # Unreleased (2.31.0-dev) #### :sparkles: Usability & Accessibility +* Fix flickering when switching between background imagery layers, make switching backgrounds snappier #### :scissors: Operations #### :camera: Street-Level #### :white_check_mark: Validation diff --git a/css/80_app.css b/css/80_app.css index 81297915b..3f5aa4942 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -4361,17 +4361,13 @@ img.tile { -webkit-user-drag: none; - opacity: 0; - - transition: opacity 200ms linear; -} - -img.tile-loaded { opacity: 1; + transition: opacity 120ms linear; } img.tile-removing { opacity: 0; + z-index: 1; } .tile-label-debug { diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js index 318a0f884..90fc7aca3 100644 --- a/modules/renderer/tile_layer.js +++ b/modules/renderer/tile_layer.js @@ -19,7 +19,7 @@ export function rendererTileLayer(context) { function tileSizeAtZoom(d, z) { var EPSILON = 0.002; // close seams - return ((_tileSize * Math.pow(2, z - d[2])) / _tileSize) + EPSILON; + return ((d.tileSize * Math.pow(2, z - d[2])) / d.tileSize) + EPSILON; } @@ -57,7 +57,8 @@ export function rendererTileLayer(context) { function addSource(d) { - d.push(_source.url(d)); + d.url = _source.url(d); + d.tileSize = _tileSize; return d; } @@ -107,31 +108,30 @@ export function rendererTileLayer(context) { tiler().forEach(function(d) { addSource(d); - if (d[3] === '') return; - if (typeof d[3] !== 'string') return; // Workaround for #2295 + if (d.url === '') return; + if (typeof d.url !== 'string') return; // Workaround for #2295 requests.push(d); - if (_cache[d[3]] === false && lookUp(d)) { + if (_cache[d.url] === false && lookUp(d)) { requests.push(addSource(lookUp(d))); } }); - requests = uniqueBy(requests, 3).filter(function(r) { + requests = uniqueBy(requests, 'url').filter(function(r) { // don't re-request tiles which have failed in the past - return _cache[r[3]] !== false; + return _cache[r.url] !== false; }); } function load(d3_event, d) { - _cache[d[3]] = true; + _cache[d.url] = true; d3_select(this) .on('error', null) - .on('load', null) - .classed('tile-loaded', true); + .on('load', null); render(selection); } function error(d3_event, d) { - _cache[d[3]] = false; + _cache[d.url] = false; d3_select(this) .on('error', null) .on('load', null) @@ -140,16 +140,18 @@ export function rendererTileLayer(context) { } function imageTransform(d) { - var ts = _tileSize * Math.pow(2, _zoom - d[2]); + var ts = d.tileSize * Math.pow(2, _zoom - d[2]); var scale = tileSizeAtZoom(d, _zoom); return 'translate(' + - ((d[0] * ts) - _tileOrigin[0]) + 'px,' + - ((d[1] * ts) - _tileOrigin[1]) + 'px) ' + - 'scale(' + scale + ',' + scale + ')'; + ((d[0] * ts) * _tileSize / d.tileSize - _tileOrigin[0] + ) + 'px,' + + ((d[1] * ts) * _tileSize / d.tileSize - _tileOrigin[1] + ) + 'px) ' + + 'scale(' + scale * _tileSize / d.tileSize + ',' + scale * _tileSize / d.tileSize + ')'; } function tileCenter(d) { - var ts = _tileSize * Math.pow(2, _zoom - d[2]); + var ts = d.tileSize * Math.pow(2, _zoom - d[2]); return [ ((d[0] * ts) - _tileOrigin[0] + (ts / 2)), ((d[1] * ts) - _tileOrigin[1] + (ts / 2)) @@ -180,7 +182,7 @@ export function rendererTileLayer(context) { var image = selection.selectAll('img') - .data(requests, function(d) { return d[3]; }); + .data(requests, function(d) { return d.url; }); image.exit() .style(transformProp, imageTransform) @@ -192,7 +194,7 @@ export function rendererTileLayer(context) { if (tile.classed('tile-removing')) { tile.remove(); } - }, 300); + }, 120); }); image.enter() @@ -202,7 +204,7 @@ export function rendererTileLayer(context) { .attr('draggable', 'false') .style('width', _tileSize + 'px') .style('height', _tileSize + 'px') - .attr('src', function(d) { return d[3]; }) + .attr('src', function(d) { return d.url; }) .on('error', error) .on('load', load) .merge(image) @@ -214,7 +216,7 @@ export function rendererTileLayer(context) { var debug = selection.selectAll('.tile-label-debug') - .data(showDebug ? requests : [], function(d) { return d[3]; }); + .data(showDebug ? requests : [], function(d) { return d.url; }); debug.exit() .remove();