Custom style layer
Use a custom style layer to render custom WebGL content.
<script lang="ts">
import { MapLibre, CustomLayer } from 'svelte-maplibre-gl';
import maplibregl from 'maplibre-gl';
class CustomLayerImpl implements Omit<maplibregl.CustomLayerInterface, 'id' | 'type'> {
program: WebGLProgram | null = null;
aPos: number = 0;
buffer: WebGLBuffer | null = null;
onAdd(_map: maplibregl.Map, gl: WebGL2RenderingContext) {
//create GLSL source for vertex shader
const vertexSource = `#version 300 es
uniform mat4 u_matrix;
in vec2 a_pos;
void main() {
gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);
}`;
// create GLSL source for fragment shader
const fragmentSource = `#version 300 es
out highp vec4 fragColor;
void main() {
fragColor = vec4(1.0, 0.0, 0.0, 0.5);
}`;
// create a vertex shader
const vertexShader = gl.createShader(gl.VERTEX_SHADER)!;
gl.shaderSource(vertexShader, vertexSource);
gl.compileShader(vertexShader);
// create a fragment shader
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)!;
gl.shaderSource(fragmentShader, fragmentSource);
gl.compileShader(fragmentShader);
// link the two shaders into a WebGL program
this.program = gl.createProgram()!;
gl.attachShader(this.program, vertexShader);
gl.attachShader(this.program, fragmentShader);
gl.linkProgram(this.program);
this.aPos = gl.getAttribLocation(this.program, 'a_pos');
// define vertices of the triangle to be rendered in the custom style layer
const helsinki = maplibregl.MercatorCoordinate.fromLngLat({ lng: 25.004, lat: 60.239 });
const berlin = maplibregl.MercatorCoordinate.fromLngLat({ lng: 13.403, lat: 52.562 });
const kyiv = maplibregl.MercatorCoordinate.fromLngLat({ lng: 30.498, lat: 50.541 });
// create and initialize a WebGLBuffer to store vertex and color data
this.buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([helsinki.x, helsinki.y, berlin.x, berlin.y, kyiv.x, kyiv.y]),
gl.STATIC_DRAW
);
}
// method fired on each animation frame
render(gl: WebGL2RenderingContext | WebGLRenderingContext, options: maplibregl.CustomRenderMethodInput) {
gl.useProgram(this.program);
gl.uniformMatrix4fv(
gl.getUniformLocation(this.program!, 'u_matrix'),
false,
options.defaultProjectionData.mainMatrix
);
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
gl.enableVertexAttribArray(this.aPos);
gl.vertexAttribPointer(this.aPos, 2, gl.FLOAT, false, 0, 0);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3);
}
}
</script>
<MapLibre
class="h-[55vh] min-h-[300px]"
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
zoom={3}
center={[20, 58]}
>
<CustomLayer implementation={new CustomLayerImpl()} />
</MapLibre>