Stacking contexts for layers, overlays, and controls

This commit is contained in:
Tim Schaub
2018-11-19 09:47:51 -07:00
parent 5d14666376
commit 898c349fbf
18 changed files with 113 additions and 42 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 136 KiB

View File

@@ -25,5 +25,5 @@ new Map({
render({ render({
message: 'Vector tile layer renders', message: 'Vector tile layer renders',
tolerance: 0.02 tolerance: 0.01
}); });

View File

@@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<link rel="stylesheet" href="/ol/ol.css" type="text/css">
<style> <style>
html, body { html, body {
margin: 0; margin: 0;
@@ -15,6 +16,9 @@
.bw { .bw {
filter: grayscale(100%); filter: grayscale(100%);
} }
.ol-control {
display: none;
}
</style> </style>
</head> </head>
<body> <body>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -67,4 +67,4 @@ new Map({
}) })
}); });
render({tolerance: 0.02}); render({tolerance: 0.01});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

@@ -1,22 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="main.js"></script>
</body>
</script>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

View File

@@ -0,0 +1,82 @@
/**
* Demonstrate stacking with z-index. Layers and controls
* can be ordered with z-index, but controls always appear
* above layers.
*/
import Map from '../../../src/ol/Map.js';
import View from '../../../src/ol/View.js';
import Layer from '../../../src/ol/layer/Layer.js';
import Control from '../../../src/ol/control/Control.js';
import SourceState from '../../../src/ol/source/State.js';
class Element extends Layer {
constructor(options, style) {
super(options);
const element = document.createElement('div');
element.style.position = 'absolute';
Object.assign(element.style, style);
this.element = element;
}
getSourceState() {
return SourceState.READY;
}
render() {
return this.element;
}
}
// elements for stacked controls
const element1 = document.createElement('div');
const style1 = element1.style;
style1.position = 'absolute';
style1.background = 'blue';
style1.width = '25%';
style1.height = '50%';
style1.zIndex = '1';
const element2 = document.createElement('div');
const style2 = element2.style;
style2.position = 'absolute';
style2.background = 'orange';
style2.width = '75%';
style2.height = '25%';
style2.zIndex = '-1';
new Map({
target: 'map',
layers: [
new Element({
zIndex: 200
}, {
background: 'red',
width: '50%',
height: '100%'
}),
new Element({
zIndex: -200
}, {
background: 'green',
width: '100%',
height: '50%'
})
],
controls: [
new Control({
element: element1
}),
new Control({
element: element2
})
],
view: new View({
center: [0, 0],
zoom: 0
})
});
render();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -120,4 +120,4 @@ new Map({
}) })
}); });
render({tolerance: 0.05}); render({tolerance: 0.02});

View File

@@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<link rel="stylesheet" href="/ol/ol.css" type="text/css">
<style> <style>
html, body { html, body {
margin: 0; margin: 0;
@@ -12,6 +13,9 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.ol-control {
display: none;
}
</style> </style>
</head> </head>
<body> <body>

View File

@@ -24,6 +24,8 @@ const staticHandler = serveStatic(__dirname);
const defaultHandler = serveStatic(path.join(__dirname, 'default')); const defaultHandler = serveStatic(path.join(__dirname, 'default'));
const srcHandler = serveStatic(path.join(__dirname, '..', 'src'));
function indexHandler(req, res) { function indexHandler(req, res) {
const items = []; const items = [];
for (const key in config.entry) { for (const key in config.entry) {
@@ -47,8 +49,8 @@ function notFound(req, res) {
return defaultHandler(req, res, () => indexHandler(req, res)); return defaultHandler(req, res, () => indexHandler(req, res));
} }
// fall back to a listing of all cases // next try the src directory (only needed for ol/ol.css)
indexHandler(req, res); return srcHandler(req, res, () => indexHandler(req, res));
}; };
} }

View File

@@ -19,7 +19,6 @@ import ViewHint from './ViewHint.js';
import {assert} from './asserts.js'; import {assert} from './asserts.js';
import {removeNode} from './dom.js'; import {removeNode} from './dom.js';
import {listen, unlistenByKey, unlisten} from './events.js'; import {listen, unlistenByKey, unlisten} from './events.js';
import {stopPropagation} from './events/Event.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
import {createEmpty, clone, createOrUpdateEmpty, equals, getForViewAndSize, isEmpty} from './extent.js'; import {createEmpty, clone, createOrUpdateEmpty, equals, getForViewAndSize, isEmpty} from './extent.js';
import {TRUE} from './functions.js'; import {TRUE} from './functions.js';
@@ -260,6 +259,10 @@ class PluggableMap extends BaseObject {
* @type {!HTMLElement} * @type {!HTMLElement}
*/ */
this.overlayContainer_ = document.createElement('div'); this.overlayContainer_ = document.createElement('div');
this.overlayContainer_.style.position = 'absolute';
this.overlayContainer_.style.zIndex = '0';
this.overlayContainer_.style.width = '100%';
this.overlayContainer_.style.height = '100%';
this.overlayContainer_.className = 'ol-overlaycontainer'; this.overlayContainer_.className = 'ol-overlaycontainer';
this.viewport_.appendChild(this.overlayContainer_); this.viewport_.appendChild(this.overlayContainer_);
@@ -268,20 +271,11 @@ class PluggableMap extends BaseObject {
* @type {!HTMLElement} * @type {!HTMLElement}
*/ */
this.overlayContainerStopEvent_ = document.createElement('div'); this.overlayContainerStopEvent_ = document.createElement('div');
this.overlayContainerStopEvent_.style.position = 'absolute';
this.overlayContainerStopEvent_.style.zIndex = '0';
this.overlayContainerStopEvent_.style.width = '100%';
this.overlayContainerStopEvent_.style.height = '100%';
this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent'; this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent';
const overlayEvents = [
EventType.CLICK,
EventType.DBLCLICK,
EventType.MOUSEDOWN,
EventType.TOUCHSTART,
EventType.MSPOINTERDOWN,
MapBrowserEventType.POINTERDOWN,
EventType.MOUSEWHEEL,
EventType.WHEEL
];
for (let i = 0, ii = overlayEvents.length; i < ii; ++i) {
listen(this.overlayContainerStopEvent_, overlayEvents[i], stopPropagation);
}
this.viewport_.appendChild(this.overlayContainerStopEvent_); this.viewport_.appendChild(this.overlayContainerStopEvent_);
/** /**
@@ -917,6 +911,13 @@ class PluggableMap extends BaseObject {
// coordinates so interactions cannot be used. // coordinates so interactions cannot be used.
return; return;
} }
let target = mapBrowserEvent.originalEvent.target;
while (target instanceof HTMLElement) {
if (target.parentElement === this.overlayContainerStopEvent_) {
return;
}
target = target.parentElement;
}
this.focus_ = mapBrowserEvent.coordinate; this.focus_ = mapBrowserEvent.coordinate;
mapBrowserEvent.frameState = this.frameState_; mapBrowserEvent.frameState = this.frameState_;
const interactionsArray = this.getInteractions().getArray(); const interactionsArray = this.getInteractions().getArray();

View File

@@ -29,9 +29,9 @@ class CompositeMapRenderer extends MapRenderer {
*/ */
this.element_ = document.createElement('div'); this.element_ = document.createElement('div');
const style = this.element_.style; const style = this.element_.style;
style.position = 'absolute';
style.width = '100%'; style.width = '100%';
style.height = '100%'; style.height = '100%';
style.position = 'relative';
style.zIndex = '0'; style.zIndex = '0';
this.element_.className = CLASS_UNSELECTABLE + ' ol-layers'; this.element_.className = CLASS_UNSELECTABLE + ' ol-layers';