diff --git a/css/60_photos.css b/css/60_photos.css index 4a5a247a9..dcd9a290c 100644 --- a/css/60_photos.css +++ b/css/60_photos.css @@ -409,12 +409,12 @@ label.streetside-hires { transform-origin: 0 0; } -.vegbilder-wrapper { +.photo-wrapper { position: relative; background-color: #000; } -.vegbilder-wrapper .plane-frame { +.photoviewer .plane-frame { display: block; overflow: hidden; height: 100%; @@ -424,7 +424,7 @@ label.streetside-hires { background-repeat: no-repeat; } -.vegbilder-wrapper .plane-frame > img.plane-photo{ +.photoviewer .plane-frame > img.plane-photo{ width: auto; height: 100%; transform-origin: 0 0; diff --git a/modules/services/plane_photo.js b/modules/services/plane_photo.js index f654ef1ea..980d01c22 100644 --- a/modules/services/plane_photo.js +++ b/modules/services/plane_photo.js @@ -12,7 +12,7 @@ let _widthOverflow; function zoomPan (d3_event) { let t = d3_event.transform; _photo.call(utilSetTransform, t.x, t.y, t.k); - } +} function zoomBeahvior () { const {width: wrapperWidth, height: wrapperHeight} = _wrapper.node().getBoundingClientRect(); @@ -58,7 +58,7 @@ export default { await Promise.resolve(); return this; - }, + }, showPhotoFrame: function (context) { const isHidden = context.selectAll('.photo-frame.plane-frame.hide').size(); @@ -74,7 +74,7 @@ export default { } return this; - }, + }, hidePhotoFrame: function (context) { @@ -83,7 +83,7 @@ export default { .classed('hide', false); return this; - }, + }, selectPhoto: function (data, keepOrientation) { dispatch.call('viewerChanged'); diff --git a/modules/services/vegbilder.js b/modules/services/vegbilder.js index 9735fd25b..fe6f506e7 100644 --- a/modules/services/vegbilder.js +++ b/modules/services/vegbilder.js @@ -500,19 +500,19 @@ export default { }, showViewer: function (context) { - const viewer = context.container().select('.photoviewer') - .classed('hide', false); - - const isHidden = viewer.selectAll('.photo-wrapper.vegbilder-wrapper.hide').size(); - - if (isHidden) { - viewer - .selectAll('.photo-wrapper:not(.vegbilder-wrapper)') - .classed('hide', true); - - viewer - .selectAll('.photo-wrapper.vegbilder-wrapper') + const viewer = context.container().select('.photoviewer') .classed('hide', false); + + const isHidden = viewer.selectAll('.photo-wrapper.vegbilder-wrapper.hide').size(); + + if (isHidden) { + viewer + .selectAll('.photo-wrapper:not(.vegbilder-wrapper)') + .classed('hide', true); + + viewer + .selectAll('.photo-wrapper.vegbilder-wrapper') + .classed('hide', false); } return this; }, @@ -532,7 +532,7 @@ export default { .classed('currentView', false); return this.setStyles(context, null, true); -}, + }, // Updates the currently highlighted sequence and selected bubble. diff --git a/modules/svg/local_photos.js b/modules/svg/local_photos.js index 7cca6aafe..c2c5a967b 100644 --- a/modules/svg/local_photos.js +++ b/modules/svg/local_photos.js @@ -1,19 +1,21 @@ import { select as d3_select } from 'd3-selection'; import exifr from 'exifr'; +import { isArray, isNumber } from 'lodash-es'; import { utilDetect } from '../util/detect'; import { geoExtent } from '../geo'; -import { isArray, isNumber } from 'lodash-es'; +import planePhotoFrame from '../services/plane_photo'; var _initialized = false; var _enabled = false; export function svgLocalPhotos(projection, context, dispatch) { - var detected = utilDetect(); + const detected = utilDetect(); let layer = d3_select(null); - var _fileList; - var _photos = []; - var _idAutoinc = 0; + let _fileList; + let _photos = []; + let _idAutoinc = 0; + let _photoFrame; function init() { if (_initialized) return; // run once @@ -41,35 +43,63 @@ export function svgLocalPhotos(projection, context, dispatch) { _initialized = true; } + function ensureViewerLoaded(context) { + if (_photoFrame) { + return Promise.resolve(_photoFrame); + } + + const viewer = context.container().select('.photoviewer') + .selectAll('.local-photos-wrapper') + .data([0]); + + const viewerEnter = viewer.enter() + .append('div') + .attr('class', 'photo-wrapper local-photos-wrapper') + .classed('hide', true); + + viewerEnter + .append('div') + .attr('class', 'photo-attribution fillD'); + + return planePhotoFrame.init(context, viewerEnter) + .then(planePhotoFrame => { + _photoFrame = planePhotoFrame; + //_photoFrame.event.on('viewerChanged', () => …); + }); + } + function closePhotoViewer() { - d3_select('.over-map').selectAll('.local-photo-viewer').remove(); + const viewer = context.container().select('.photoviewer'); + if (!viewer.empty()) viewer.datum(null); + + viewer + .classed('hide', true) + .selectAll('.photo-wrapper') + .classed('hide', true); } // opens the image at bottom left function click(d3_event, image, zoomTo) { - // removes old div(s), if any - closePhotoViewer(); + ensureViewerLoaded(context).then(() => { + const viewer = context.container().select('.photoviewer') + .classed('hide', false); - var image_container = d3_select('.over-map') - .append('div') - .attr('style', 'position: relative;margin: 5px;border: 5px solid white;') - .attr('class', 'local-photo-viewer'); + const viewerWrap = viewer.select('.local-photos-wrapper') + .classed('hide', false); - image_container - .append('button') - .text('X') - .on('click', function(d3_event) { - d3_event.preventDefault(); - closePhotoViewer(); - }) - .attr('style', 'position: absolute;right: 0;padding: 3px 10px;font-size: medium;border-radius:0;'); + const attribution = viewerWrap.selectAll('.photo-attribution').text(''); - image_container - .append('img') - .attr('src', image.src) - .attr('width', 400) - .attr('height', 300); + if (image.name) { + attribution + .append('span') + .classed('filename', true) + .text(image.name); + } + _photoFrame + .selectPhoto({ image_path: image.src }, false) + .showPhotoFrame(viewerWrap); + }); // centers the map with image location if (zoomTo) { diff --git a/modules/ui/settings/local_photos.js b/modules/ui/settings/local_photos.js index a7de7a721..07c0b834c 100644 --- a/modules/ui/settings/local_photos.js +++ b/modules/ui/settings/local_photos.js @@ -1,10 +1,10 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; import { select as d3_select } from 'd3-selection'; +import { isArray, isNumber } from 'lodash-es'; import { t } from '../../core/localizer'; import { uiConfirm } from '../confirm'; import { utilRebind } from '../../util'; -import { isArray, isNumber } from 'lodash-es'; import { uiTooltip } from '../tooltip'; import { svgIcon } from '../../svg';