mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-28 06:36:19 +02:00
Panning map-in-map now recenters main map
This commit is contained in:
+15
-3
@@ -2107,7 +2107,7 @@ img.wiki-image {
|
||||
/* Map-In-Map
|
||||
------------------------------------------------------- */
|
||||
|
||||
.map-in-map-wrap {
|
||||
.map-in-map {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: 60px;
|
||||
@@ -2117,13 +2117,25 @@ img.wiki-image {
|
||||
background: #000;
|
||||
border: #aaa 1px solid;
|
||||
box-shadow: 0 0 2em black;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.map-in-map-wrap svg {
|
||||
.map-in-map-tiles {
|
||||
transform-origin:0 0;
|
||||
-ms-transform-origin:0 0;
|
||||
-webkit-transform-origin:0 0;
|
||||
-moz-transform-origin:0 0;
|
||||
-o-transform-origin:0 0;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.map-in-map-svg {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.map-in-map-bbox {
|
||||
|
||||
@@ -1032,6 +1032,7 @@ g.turn circle {
|
||||
|
||||
/* Cursors */
|
||||
|
||||
.map-in-map,
|
||||
#map {
|
||||
cursor: auto; /* Opera */
|
||||
cursor: url(img/cursor-grab.png) 9 9, auto; /* FF */
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ iD.ui = function(context) {
|
||||
.call(map);
|
||||
|
||||
content.append('div')
|
||||
.attr('class', 'map-in-map-wrap')
|
||||
.attr('class', 'map-in-map')
|
||||
.style('display', 'none')
|
||||
.call(iD.ui.MapInMap(context));
|
||||
|
||||
|
||||
+145
-42
@@ -1,37 +1,121 @@
|
||||
iD.ui.MapInMap = function(context) {
|
||||
var key = 'M',
|
||||
backgroundLayer = iD.TileLayer(),
|
||||
overlayLayer = iD.TileLayer();
|
||||
var key = 'M';
|
||||
|
||||
function map_in_map(selection) {
|
||||
var backgroundLayer = iD.TileLayer(),
|
||||
overlayLayer = iD.TileLayer(),
|
||||
projection = iD.geo.RawMercator(),
|
||||
zoom = d3.behavior.zoom()
|
||||
// .scaleExtent([1024, 256 * Math.pow(2, 24)])
|
||||
.on('zoom', zoomPan),
|
||||
transformed = false,
|
||||
panning = false,
|
||||
tLast = [0, 0],
|
||||
tCurr = [0, 0],
|
||||
tiles,
|
||||
timeoutId;
|
||||
|
||||
function render() {
|
||||
if (hidden()) return;
|
||||
|
||||
function startZoomPan() {
|
||||
context.surface().on('mouseup.map-in-map-outside', endZoomPan);
|
||||
context.container().on('mouseup.map-in-map-outside', endZoomPan);
|
||||
}
|
||||
|
||||
|
||||
function zoomPan() {
|
||||
var t = d3.event.translate,
|
||||
e = d3.event.sourceEvent;
|
||||
|
||||
if (e.type === 'wheel') {
|
||||
// for now, throw out wheel events
|
||||
zoom.translate(tCurr).scale(1);
|
||||
|
||||
} else if (e.type === 'mousemove') {
|
||||
var tDiff = [ t[0] - tLast[0], t[1] - tLast[1] ];
|
||||
tCurr = t;
|
||||
|
||||
iD.util.setTransform(tiles, tDiff[0], tDiff[1]);
|
||||
transformed = true;
|
||||
panning = true;
|
||||
queueRedraw();
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
|
||||
function endZoomPan() {
|
||||
context.surface().on('mouseup.map-in-map-outside', null);
|
||||
context.container().on('mouseup.map-in-map-outside', null);
|
||||
|
||||
updateProjection();
|
||||
|
||||
tLast = [0, 0];
|
||||
tCurr = [0, 0];
|
||||
zoom.translate([0, 0]).scale(1);
|
||||
panning = false;
|
||||
|
||||
var d = selection.dimensions(),
|
||||
c = [ d[0] / 2, d[1] / 2 ];
|
||||
|
||||
context.map().center(projection.invert(c));
|
||||
}
|
||||
|
||||
|
||||
function updateProjection() {
|
||||
var loc = context.map().center(),
|
||||
d = selection.dimensions(),
|
||||
c = [d[0] / 2, d[1] / 2],
|
||||
c = [ d[0] / 2, d[1] / 2 ],
|
||||
k1 = context.projection.scale(),
|
||||
z1 = Math.log(k1 * 2 * Math.PI) / Math.LN2 - 8,
|
||||
z = Math.max(z1 - 6, 2);
|
||||
|
||||
var projection = iD.geo.RawMercator()
|
||||
.scale(256 * Math.pow(2, z) / (2 * Math.PI));
|
||||
|
||||
var s = projection(loc);
|
||||
z = Math.max(z1 - 6, 0.5);
|
||||
|
||||
projection
|
||||
.translate([c[0] - s[0], c[1] - s[1]])
|
||||
.translate([0,0])
|
||||
.scale(256 * Math.pow(2, z) / (2 * Math.PI));
|
||||
|
||||
var s = projection(loc),
|
||||
t = [c[0] - s[0] + tCurr[0],
|
||||
c[1] - s[1] + tCurr[1] ];
|
||||
|
||||
projection
|
||||
.translate(t)
|
||||
.clipExtent([[0, 0], d]);
|
||||
}
|
||||
|
||||
|
||||
// render background
|
||||
function redraw() {
|
||||
if (hidden()) return;
|
||||
|
||||
updateProjection();
|
||||
|
||||
var d = selection.dimensions(),
|
||||
z = Math.log(projection.scale() * 2 * Math.PI) / Math.LN2 - 8;
|
||||
|
||||
// setup tile container
|
||||
tiles = selection
|
||||
.selectAll('.map-in-map-tiles')
|
||||
.data([0]);
|
||||
|
||||
tiles
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'map-in-map-tiles');
|
||||
|
||||
if (transformed) {
|
||||
tLast = tCurr;
|
||||
iD.util.setTransform(tiles, 0, 0);
|
||||
transformed = false;
|
||||
}
|
||||
|
||||
// redraw background
|
||||
backgroundLayer
|
||||
.source(context.background().baseLayerSource())
|
||||
.projection(projection)
|
||||
.dimensions(d);
|
||||
|
||||
var background = selection
|
||||
var background = tiles
|
||||
.selectAll('.map-in-map-background')
|
||||
.data([0]);
|
||||
|
||||
@@ -42,8 +126,7 @@ iD.ui.MapInMap = function(context) {
|
||||
background
|
||||
.call(backgroundLayer);
|
||||
|
||||
|
||||
// render overlay
|
||||
// redraw overlay
|
||||
var overlaySources = context.background().overlayLayerSources(),
|
||||
hasOverlay = false;
|
||||
|
||||
@@ -59,7 +142,7 @@ iD.ui.MapInMap = function(context) {
|
||||
}
|
||||
}
|
||||
|
||||
var overlay = selection
|
||||
var overlay = tiles
|
||||
.selectAll('.map-in-map-overlay')
|
||||
.data(hasOverlay ? [0] : []);
|
||||
|
||||
@@ -70,29 +153,39 @@ iD.ui.MapInMap = function(context) {
|
||||
overlay.exit()
|
||||
.remove();
|
||||
|
||||
overlay
|
||||
.call(overlayLayer);
|
||||
if (hasOverlay) {
|
||||
overlay
|
||||
.call(overlayLayer);
|
||||
}
|
||||
|
||||
// redraw bounding box
|
||||
if (!panning) {
|
||||
var getPath = d3.geo.path().projection(projection),
|
||||
bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
|
||||
|
||||
var svg = selection.selectAll('.map-in-map-svg')
|
||||
.data([0]);
|
||||
|
||||
svg.enter()
|
||||
.append('svg')
|
||||
.attr('class', 'map-in-map-svg');
|
||||
|
||||
var path = svg.selectAll('.map-in-map-bbox')
|
||||
.data([bbox]);
|
||||
|
||||
path.enter()
|
||||
.append('path')
|
||||
.attr('class', 'map-in-map-bbox');
|
||||
|
||||
path
|
||||
.attr('d', getPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// render bounding box
|
||||
var getPath = d3.geo.path().projection(projection),
|
||||
bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
|
||||
|
||||
var svg = selection.selectAll('svg')
|
||||
.data([0]);
|
||||
|
||||
svg.enter()
|
||||
.append('svg');
|
||||
|
||||
var path = svg.selectAll('path')
|
||||
.data([bbox]);
|
||||
|
||||
path.enter()
|
||||
.append('path')
|
||||
.attr('class', 'map-in-map-bbox');
|
||||
|
||||
path
|
||||
.attr('d', getPath);
|
||||
function queueRedraw() {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(function() { redraw(); }, 300);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +205,7 @@ iD.ui.MapInMap = function(context) {
|
||||
.duration(200)
|
||||
.style('opacity', 1);
|
||||
|
||||
render();
|
||||
redraw();
|
||||
|
||||
} else {
|
||||
selection
|
||||
@@ -128,8 +221,18 @@ iD.ui.MapInMap = function(context) {
|
||||
}
|
||||
|
||||
|
||||
context.map().on('drawn.map-in-map', render);
|
||||
render();
|
||||
selection
|
||||
.on('mousedown.map-in-map', startZoomPan)
|
||||
.on('mouseup.map-in-map', endZoomPan);
|
||||
|
||||
selection
|
||||
.call(zoom)
|
||||
.on('dblclick.zoom', null);
|
||||
|
||||
context.map()
|
||||
.on('drawn.map-in-map', redraw);
|
||||
|
||||
redraw();
|
||||
|
||||
var keybinding = d3.keybinding('map-in-map')
|
||||
.on(key, toggle);
|
||||
|
||||
Reference in New Issue
Block a user