TomTom Maps for JavaScript
    Preparing search index...

    Class MapEffects

    Practical post-processing for a TomTomMap, with effects computed from the rendered map's own pixels rather than its style. They therefore work on every style, survive every style release, and cannot be reproduced by editing the style at all.

    Every effect is named by the problem it solves, and off by default:

    • bloom - Emphasis on dark and driving styles. Lit roads, traffic tubes and route lines glow.
    • grade (brightness, contrast, saturation) and tint - Muting the base map so a data overlay reads first.
    • fog - Depth. The rim is blurred and washed towards the colour of the air, which follows the map's light/dark theme.
    • edge blur - Focus. The rim is blurred and keeps its colour, so it reads as a lens rather than as distance.
    • depth of field - Depth on a tilted map. One band of distance stays sharp and the rest defocuses, worked out from the camera's pitch and field of view, so a flat map ends it.
    • vignette - Focus too, by darkening or lightening the edges.

    Effects render live as layers over the map canvas, and are composited the same way into capture, so what is captured is what was on screen. From the bottom, the layers are a WebGL2 chain that also runs your own passes from addPass, bloom as a small canvas blended in screen mode, and the CSS overlays.

    Bloom, the depth of field, your passes and capture read the map canvas, which needs mapLibre: { canvasContextAttributes: { preserveDrawingBuffer: true } } when creating the map. The plugin warns once when it is missing.

    effectKnobCatalogue lists every knob as static data, the way stylingFoundationsKnobCatalogue lists the SDK's styling knobs. Each id is its path into MapEffectsConfig. The SDK's setKnob, setKnobs, getKnob and resetKnob set, read and unset knobs by id, as on a map module.

    import { setKnob, setKnobs } from '@tomtom-org/maps-sdk/map';
    import { effectKnobCatalogue, MapEffects } from '@tomtom-org/maps-sdk-plugin-map-effects';

    const effects = new MapEffects(map);
    // The data-viz muting half: a dim, desaturated base under your own layers.
    effects.applyConfig({ grade: { saturation: 0.4, brightness: 0.85 }, tint: { opacity: 0.15 } });
    // Night-driving emphasis on a dark style, keeping the rest:
    setKnobs(effects, effectKnobCatalogue, { 'bloom.intensity': 0.5, 'bloom.threshold': 0.6 });
    setKnob(effects, effectKnobCatalogue, 'vignette.intensity', -0.4);

    const poster = await effects.capture({ pixelRatio: 3 });
    Index
    • Attaches the effects to a map. Nothing is visible until a knob turns an effect on.

      Parameters

      • map: TomTomMap

        The map to render effects over.

      • Optionalconfig: MapEffectsConfig

        Effect knob values to apply right away.

      Returns MapEffects

    • Runs a GPU pass of your own in the effects chain, ahead of every overlay effect, and in capture as on screen. Passes run in the order they were added, within their placement.

      Parameters

      Returns void

      A pass redraws with the map. If its uniforms change on their own, as in a time-driven animation, ask for frames with map.mapLibreMap.triggerRepaint(). A pass that shifts hues runs before bloom's colour key too, so a bloom.only scope may need a wider bloom.onlyTolerance.

      Error when the pass has no id or its shader does not compile, with the compiler's log; RangeError for an unknown placement. A shader is checked only while there is a WebGL2 context: without one no pass runs and the plugin warns once, and after a lost one it is checked on restore.

      effects.addPass({
      id: 'posterise',
      fragment: `uniform float uLevels;
      void main() {
      vec4 colour = texture(uSource, vUv);
      fragColor = vec4(floor(colour.rgb * uLevels) / uLevels, colour.a);
      }`,
      uniforms: { uLevels: 5 },
      });
    • Replaces the whole configuration. An empty object turns everything off.

      Parameters

      Returns void

      Use it, and updateConfig, for a look your code writes, such as a use case swapped in whole: as on a map module, the type is the check, and the values are not checked again. For values held as data, the SDK's setKnobs checks each against the catalogue and sets them by id.

      effects.applyConfig({ grade: { saturation: 0.4, brightness: 0.85 }, tint: { opacity: 0.15 } });
      
    • Renders the current view, with its effects, into a canvas, optionally at a higher pixel ratio for print. The map is re-rendered at that ratio (never resampled), read back once every tile is drawn, and then set back to the ratio it had.

      Parameters

      Returns Promise<HTMLCanvasElement>

      It needs preserveDrawingBuffer: true on the map's canvas context. Without it, the map half of the capture is blank. Viewers cannot download from a sandboxed page, so hand the canvas to your own upload or toBlob flow.

    • Detaches the effects from the map, removes their elements and releases the WebGL context the chain holds. A page with several maps needs this, since a browser caps how many contexts it may keep alive.

      Returns void

    • Takes a pass added with addPass out of the chain. An id with no pass is ignored.

      Parameters

      • id: string

      Returns void

    • Resets every knob to its default, off for most effects.

      Returns void

    • Changes the given effects and keeps the others, one level deep as a map module's updateConfig does: an effect you pass replaces that effect's values.

      Parameters

      Returns void

      To change some values of an effect and keep its others, use the SDK's setKnobs: setKnobs(effects, effectKnobCatalogue, { 'bloom.intensity': 0.5 }).

      effects.updateConfig({ bloom: { intensity: 0.5, threshold: 0.6 } }); // the bloom's radius goes back to its default