0

I'm trying to follow an example from OpenLayers.

https://openlayers.org/en/latest/examples/layer-swipe.html

I've imported what I need and I'm working on implementing the example in my code but I'm running into an issue where the properties of the "event.context" don't exist?

The code looks like this

const imagery = new TileLayer({
  source: new XYZ({
    url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + 
          'key',
    maxZoom: 20,
  }),
});
map.addLayer(imagery);

const swipe = <HTMLInputElement> document.getElementById('swipe');

imagery.on('prerender', function (event) {
  const ctx = event.context;
  const mapSize = map.getSize();
  const width = mapSize[0] * (+swipe.value / 100);
  const tl = getRenderPixel(event, [width, 0]);
  const tr = getRenderPixel(event, [mapSize[0], 0]);
  const bl = getRenderPixel(event, [width, mapSize[1]]);
  const br = getRenderPixel(event, mapSize);

  ctx.save();
  ctx.beginPath();
  ctx.moveTo(tl[0], tl[1]);
  ctx.lineTo(bl[0], bl[1]);
  ctx.lineTo(br[0], br[1]);
  ctx.lineTo(tr[0], tr[1]);
  ctx.closePath();
  ctx.clip();
});

but every property of "ctx" throws an error saying it doesn't exist? A specific example of one of the errors is

TS2339: Property 'save' does not exist on type 'CanvasRenderingContext2D | WebGLRenderingContext'.

It seems like maybe it's using the wrong object type but I'm not sure and everything I've tried hasn't worked...any help would be greatly appreciated!

Funn_Bobby
  • 647
  • 1
  • 20
  • 57
  • 1
    The event type applies to both 2d canvas and webgl layers. The example uses a canvas layer. If you are using typescript you must indicate it is a 2d canvas context `const ctx = event.context;`. If you used the webgl layer https://openlayers.org/en/main/examples/webgl-layer-swipe.html then you would have a `WebGLRenderingContext` with properties which do not exist on a 2d canvas context. – Mike Mar 14 '23 at 17:04
  • Thank You!! This should really be added into the example! (Maybe it is and I missed it?) So this is "kind of" working now...the scissors only move right and do not move left? Any ideas why that may be?...my code currently mirrors the working example outside of adding – Funn_Bobby Mar 14 '23 at 18:24
  • For anyone else that finds this post there is another thread that references the issue above...https://stackoverflow.com/questions/72562678/layer-swipe-implementation-for-tilelayer-and-webgltilelayer – Funn_Bobby Mar 14 '23 at 20:51

1 Answers1

0

Based on Mikes answer above and the other thread I got the WebGl scissors to work like this.

const imagery = new TileLayer({
  source: new XYZ({
    url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + '19eciGimIzBlp29oJUJO',
    maxZoom: 20,
  }),
});
map.addLayer(imagery);

const swipe = <HTMLInputElement> document.getElementById('swipe');

imagery.on('prerender', function (event) {
  const gl = <WebGLRenderingContext> event.context;
  gl.clear(gl.COLOR_BUFFER_BIT);
  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 = (topRight[0] - bottomLeft[0]) * (Number(swipe.value) / 100);
  const height = topRight[1] - bottomLeft[1];
  gl.scissor(bottomLeft[0], bottomLeft[1], width, height);

});

imagery.on('postrender', function (event) {
  const gl = <WebGLRenderingContext> event.context;
  gl.disable(gl.SCISSOR_TEST);
});
const listener = function () {
  map.render();
};
swipe.addEventListener('input', listener);
swipe.addEventListener('change', listener);
Funn_Bobby
  • 647
  • 1
  • 20
  • 57