5

I'm looking for an open source implementation of the off-screen canvas technique in Leaflet. This technique is useful to speed rendering of many thousands of like images to an HTML5 Canvas: The image is drawn once to a canvas object that is not part of the HTML document, and then copied (as a bitmap) repeatedly to the visible canvas.

Here's an excerpt from Dense canvas, offscreen (@ckrahe) on CodePen:

_offscreen = document.createElement("canvas");
_otx = _offscreen.getContext("2d");
_otx.arc(CIRCLE_RADIUS, CIRCLE_RADIUS, CIRCLE_RADIUS, 0, (2*Math.PI));
_otx.fillStyle = "#0000ff";
_otx.fill();
...
_ctx.drawImage(_offscreen, (x - CIRCLE_RADIUS), (y - CIRCLE_RADIUS));

This canvas app (i.e. non-Leaflet) draws 50,000 circles in a fraction of the time than the naive approach draws 1,000 (where each arc is rendered and styled individually).

Consider this admittedly-contrived Leaflet 1.2 example (it randomly generates 50,000 L.CircleMarkers). Each time the map moves, the 'moveend' event triggers internal Leaflet calls to Canvas._updatePaths. The supporting method, _updateCircle, invokes 'arc' directly to the visible canvas.

_updateCircle: function (layer) {

    if (!this._drawing || layer._empty()) { return; }

    var p = layer._point,
        ctx = this._ctx,
        r = layer._radius,
        s = (layer._radiusY || r) / r;

    this._drawnLayers[layer._leaflet_id] = layer;

    if (s !== 1) {
        ctx.save();
        ctx.scale(1, s);
    }

    ctx.beginPath();
    ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);

    if (s !== 1) {
        ctx.restore();
    }

    this._fillStroke(ctx, layer);
},

Clearly each L.CircleMarker has its own Options object reference and, possibly, style. But it's at least conceivable that a plugin could, perhaps with a hint, detect like layers and optimize their drawing.

Thoughts?

1
  • Did you ever find a solution for this? The only answer here suggesting leaflet.canvas-markers isn't exactly what you meant. I have a similar scenario where I need to frequently draw large amounts of geometries on the map (i.e. on every pan, data is fetched and then drawn), and the browser drawing stalls the web page. Being able to transfer the actual drawing action to an offscreen canvas in a worker might help. What was your solution? Commented Dec 17, 2022 at 0:44

1 Answer 1

1

There are a number of plugins to Leaflet that use Canvas. One that springs to mind is Leaflet.Canvas-Markers. This possibly sounds like it might fit your use case?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.