Include WebGL context in render events for WebGL layers

This commit is contained in:
Tim Schaub
2021-10-28 18:43:04 -06:00
parent aff751bdf0
commit 2adf74ece4
8 changed files with 172 additions and 20 deletions

View File

@@ -0,0 +1,16 @@
---
layout: example.html
title: Layer Swipe (WebGL)
shortdesc: Cropping a WebGL tile layer
docs: >
The <code>prerender</code> and <code>postrender</code> events on a WebGL tile layer can be
used to manipulate the WebGL context before and after rendering. In this case, the
<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/scissor"><code>gl.scissor()</code></a>
method is called to clip the top layer based on the position of a slider.
tags: "swipe, webgl"
cloak:
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
value: Get your own API key at https://www.maptiler.com/cloud/
---
<div id="map" class="map"></div>
<input id="swipe" type="range" style="width: 100%">

View File

@@ -0,0 +1,61 @@
import Map from '../src/ol/Map.js';
import OSM from '../src/ol/source/OSM.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
import XYZ from '../src/ol/source/XYZ.js';
import {getRenderPixel} from '../src/ol/render.js';
const osm = new TileLayer({
source: new OSM({wrapX: true}),
});
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
const imagery = new TileLayer({
source: new XYZ({
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
attributions:
'<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> ' +
'<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',
crossOrigin: '',
maxZoom: 20,
}),
});
const map = new Map({
layers: [osm, imagery],
target: 'map',
view: new View({
center: [0, 0],
zoom: 2,
}),
});
const swipe = document.getElementById('swipe');
imagery.on('prerender', function (event) {
const gl = event.context;
gl.enable(gl.SCISSOR_TEST);
const mapSize = map.getSize(); // [width, height] in CSS pixels
// get render coordinates and dimensions given CSS coordinates
const bottomLeft = getRenderPixel(event, [0, mapSize[1]]);
const topRight = getRenderPixel(event, [mapSize[0], 0]);
const width = Math.round((topRight[0] - bottomLeft[0]) * (swipe.value / 100));
const height = topRight[1] - bottomLeft[1];
gl.scissor(bottomLeft[0], bottomLeft[1], width, height);
});
imagery.on('postrender', function (event) {
const gl = event.context;
gl.disable(gl.SCISSOR_TEST);
});
const listener = function () {
map.render();
};
swipe.addEventListener('input', listener);
swipe.addEventListener('change', listener);