From e57914d77e908eb919513f6dce3088a3c25f77fe Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 30 May 2016 03:20:43 -0400 Subject: [PATCH] WIP: preload viewer when layer enabled, still bad issues with slow load timing --- js/id/services/mapillary.js | 58 ++++++++-------- js/id/svg/mapillary_images.js | 119 +++++++++++--------------------- js/id/svg/mapillary_signs.js | 16 ++--- test/spec/services/mapillary.js | 9 +-- 4 files changed, 78 insertions(+), 124 deletions(-) diff --git a/js/id/services/mapillary.js b/js/id/services/mapillary.js index e2745bdb1..4183c339a 100644 --- a/js/id/services/mapillary.js +++ b/js/id/services/mapillary.js @@ -1,6 +1,6 @@ iD.services.mapillary = function() { var mapillary = {}, - dispatch = d3.dispatch('loadedImages', 'loadedSigns'), + dispatch = d3.dispatch('loadedImages', 'loadedSigns', 'loadedViewer'), apibase = 'https://a.mapillary.com/v2/', viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css', viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js', @@ -33,7 +33,9 @@ iD.services.mapillary = function() { }); } - function loadViewer() { + function loadViewer(imageKey) { + imageKey = imageKey || defaultKey; + // mapillary-wrap var wrap = d3.select('#content').selectAll('.mapillary-wrap') .data([0]); @@ -72,12 +74,13 @@ iD.services.mapillary = function() { .attr('src', viewerjs) .on('load', function() { if (Mapillary) { - iD.services.mapillary.viewer = new Mapillary.Viewer('mly', clientId, defaultKey, { + iD.services.mapillary.viewer = new Mapillary.Viewer('mly', clientId, imageKey, { baseImageSize: 320, imagePlane: false, cover: false, debug: false }); + dispatch.loadedViewer(iD.services.mapillary.viewer); } }); } @@ -261,36 +264,21 @@ iD.services.mapillary = function() { return iD.services.mapillary.sign_defs[country][type]; }; - - mapillary.showViewer = function(imageKey) { - if (!imageKey) return; - - var wrap = d3.select('#content').selectAll('.mapillary-wrap'); - - // Update - wrap + mapillary.showViewer = function() { + d3.select('#content') + .selectAll('.mapillary-wrap') .classed('hidden', false) .selectAll('.mly-wrapper') - .attr('class', 'active'); - - if (iD.services.mapillary.viewer) { - iD.services.mapillary.viewer.moveToKey(imageKey); - } else { - loadViewer(); - } + .classed('active', true); return mapillary; }; mapillary.hideViewer = function() { - if (iD.services.mapillary) { - iD.services.mapillary.image = null; - } - - d3.select('#content').selectAll('.mapillary-wrap') - .classed('hidden', true); - - d3.select('#content').selectAll('.mly-wrapper') + d3.select('#content') + .selectAll('.mapillary-wrap') + .classed('hidden', true) + .selectAll('.mly-wrapper') .classed('active', false); d3.selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign') @@ -299,13 +287,27 @@ iD.services.mapillary = function() { return mapillary; }; - mapillary.selectedImage = function(image) { + mapillary.getImage = function() { if (!iD.services.mapillary) return null; - if (!arguments.length) return iD.services.mapillary.image; + return iD.services.mapillary.image; + }; + + mapillary.setImage = function(image, fromViewer) { + if (!iD.services.mapillary) return null; + if (iD.services.mapillary.image && iD.services.mapillary.image.key === image.key) return; + iD.services.mapillary.image = image; d3.selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign') .classed('selected', function(d) { return d.key === image.key; }); + + if (!fromViewer) { + if (iD.services.mapillary.viewer) { + iD.services.mapillary.viewer.moveToKey(image.key); + } else { + loadViewer(image.key); + } + } }; mapillary.reset = function() { diff --git a/js/id/svg/mapillary_images.js b/js/id/svg/mapillary_images.js index 4ff8bb680..8bf13470d 100644 --- a/js/id/svg/mapillary_images.js +++ b/js/id/svg/mapillary_images.js @@ -2,7 +2,8 @@ iD.svg.MapillaryImages = function(projection, context, dispatch) { var debouncedRedraw = _.debounce(function () { dispatch.change(); }, 1000), minZoom = 12, layer = d3.select(null), - _mapillary, _viewer; //, _mlyLoading, pendingImg; + pendingImg, + _mapillary; function init() { @@ -13,71 +14,24 @@ iD.svg.MapillaryImages = function(projection, context, dispatch) { function getMapillary() { if (iD.services.mapillary && !_mapillary) { - _mapillary = iD.services.mapillary().on('loadedImages', debouncedRedraw); + _mapillary = iD.services.mapillary() + .on('loadedImages', debouncedRedraw) + .on('loadedViewer', function(viewer) { + viewer.on('nodechanged', nodeChanged); + }); } else if (!iD.services.mapillary && _mapillary) { _mapillary = null; } return _mapillary; } - // function showLoading(image) { - // var mapillary = getMapillary(); - // if (!mapillary) return; - // pendingImg = image; - // d3.selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign') - // .classed('loading', function(d) { return d.key === image.key; }); - // } - - function showViewer(image) { - var mapillary = getMapillary(); - if (!mapillary) return; - - mapillary.showViewer(image.key); - - if (!_viewer) { - _viewer = iD.services.mapillary.viewer; - _viewer.on('nodechanged', viewerNavHandler); - - // To avoid edge case, when network is too slow and user clicks on multiple viewfield-groups - // _viewer.on('loadingchanged', function(s) { - // if (!s && pendingImg) { - // d3.selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign') - // .classed('loading', function() { return false; }); - // mapillary.selectedImage(pendingImg); - // context.map().centerEase(pendingImg.loc); - // showViewer(pendingImg); - // pendingImg = null; - // } - // _mlyLoading = s; - // }); - } - } - - function hideViewer() { - var mapillary = getMapillary(); - if (mapillary) { - mapillary.hideViewer(); - } else { - d3.select('#content').selectAll('.mapillary-wrap') - .remove(); - } - - if (_viewer) { - _viewer.off('nodechanged'); - // _viewer.off('loadingchanged'); - _viewer = null; - } - - // _mlyLoading = null; - // pendingImg = null; - } - function showLayer() { var mapillary = getMapillary(); if (!mapillary) return; mapillary.loadViewer(); editOn(); + layer .style('opacity', 0) .transition() @@ -87,8 +41,13 @@ iD.svg.MapillaryImages = function(projection, context, dispatch) { } function hideLayer() { + var mapillary = getMapillary(); + if (mapillary) { + mapillary.hideViewer(); + } + debouncedRedraw.cancel(); - hideViewer(); + layer .transition() .duration(500) @@ -106,19 +65,34 @@ iD.svg.MapillaryImages = function(projection, context, dispatch) { } function click(d) { + // if (pendingImg) return; // block clicks if waiting for previous marker + + var mapillary = getMapillary(); + if (mapillary) { + // pendingImg = d.key; + context.map().centerEase(d.loc); + mapillary.setImage(d); + } + } + + function nodeChanged(d) { var mapillary = getMapillary(); if (!mapillary) return; - var image = mapillary.selectedImage(); - if (image && image.key === d.key) return; + var image = mapillary.getImage(); + if (!image) return; // user has never clicked a marker.. - // if (_mlyLoading) { - // showLoading(d); + // if (pendingImg) { // waiting for a marker the user clicked on + // if (d.key !== pendingImg) return; + // pendingImg = null; // unblock clicks // } else { - mapillary.selectedImage(d); - context.map().centerEase(d.loc); - showViewer(d); + // // user didn't click a marker, this change came from the viewer. + var loc = d.apiNavImIm ? [d.apiNavImIm.lon, d.apiNavImIm.lat] : [d.latLon.lon, d.latLon.lat]; + context.map().centerEase(loc); + mapillary.setImage(d, true); // } + + mapillary.showViewer(); } function transform(d) { @@ -129,7 +103,8 @@ iD.svg.MapillaryImages = function(projection, context, dispatch) { function update() { var mapillary = getMapillary(), - data = (mapillary ? mapillary.images(projection, layer.dimensions()) : []); + data = (mapillary ? mapillary.images(projection, layer.dimensions()) : []), + image = mapillary ? mapillary.getImage() : null; var markers = layer.selectAll('.viewfield-group') .data(data, function(d) { return d.key; }); @@ -138,6 +113,7 @@ iD.svg.MapillaryImages = function(projection, context, dispatch) { var enter = markers.enter() .append('g') .attr('class', 'viewfield-group') + .classed('selected', function(d) { return image && d.key === image.key; }) .on('click', click); enter.append('path') @@ -185,23 +161,6 @@ iD.svg.MapillaryImages = function(projection, context, dispatch) { } } - function viewerNavHandler(node) { - var mapillary = getMapillary(); - if (!mapillary) return; - - var image = mapillary.selectedImage(); - if (!image || image.key === node.key) return; - - d3.selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign') - .classed('selected', function(d) { - if (d.key === node.key) { - mapillary.selectedImage(d); - context.map().centerEase(d.loc); - return true; - } - }); - } - drawImages.enabled = function(_) { if (!arguments.length) return iD.svg.MapillaryImages.enabled; iD.svg.MapillaryImages.enabled = _; diff --git a/js/id/svg/mapillary_signs.js b/js/id/svg/mapillary_signs.js index 478e064d2..92a2f949d 100644 --- a/js/id/svg/mapillary_signs.js +++ b/js/id/svg/mapillary_signs.js @@ -41,19 +41,16 @@ iD.svg.MapillarySigns = function(projection, context, dispatch) { function click(d) { var mapillary = getMapillary(); - if (!mapillary) return; - - var image = mapillary.selectedImage(); - if (image && image.key === d.key) return; - - mapillary.selectedImage(d); - context.map().centerEase(d.loc); - mapillary.showViewer(d.key); + if (mapillary) { + context.map().centerEase(d.loc); + mapillary.setImage(d); + } } function update() { var mapillary = getMapillary(), - data = (mapillary ? mapillary.signs(projection, layer.dimensions()) : []); + data = (mapillary ? mapillary.signs(projection, layer.dimensions()) : []), + image = mapillary ? mapillary.getImage() : null; var signs = layer.selectAll('.icon-sign') .data(data, function(d) { return d.key; }); @@ -64,6 +61,7 @@ iD.svg.MapillarySigns = function(projection, context, dispatch) { .attr('class', 'icon-sign') .attr('width', '32px') // for Firefox .attr('height', '32px') // for Firefox + .classed('selected', function(d) { return image && d.key === image.key; }) .on('click', click); enter diff --git a/test/spec/services/mapillary.js b/test/spec/services/mapillary.js index d969754f5..b2a9dc79b 100644 --- a/test/spec/services/mapillary.js +++ b/test/spec/services/mapillary.js @@ -360,15 +360,10 @@ describe('iD.services.mapillary', function() { }); }); - describe('#selectedImage', function() { - it('sets selected image', function() { - mapillary.selectedImage('foo'); - expect(iD.services.mapillary.image).to.eql('foo'); - }); - + describe('#getImage', function() { it('gets selected image', function() { iD.services.mapillary.image = 'bar'; - expect(mapillary.selectedImage()).to.eql('bar'); + expect(mapillary.getImage()).to.eql('bar'); }); });