Leaflet - CanvasLayer: как заставить анимированные объекты правильно перемещаться при перетаскивании карты? - PullRequest
0 голосов
/ 03 июля 2018

Попытка добавить слой Canvas поверх Bing TileLayer, используя расширения ниже. В дополнение к этому я хотел бы анимировать рисунок холста, используя RequestAnimationFrame. Проблема в том, что кажется, что при перетаскивании точка перемещается больше, чем должна (см. Видео). Однако в конце перемещения он возвращается в нужное место.

scrolling map with mouse

Я пробовал разные методы, либо наследуя CanvasLayer и переопределяя render (), либо устанавливая делегат, всегда один и тот же результат.

Вот соответствующая часть кода:

// layer creation (TypeScript)
this.mapCanvasLayer = new L.CanvasLayer();
this.mapCanvasLayer.delegate(this).addTo(map);

// L.canvasLayer()
//     .delegate(this) // -- if we do not inherit from L.CanvasLayer we can setup a delegate to receive events from L.CanvasLayer
//     .addTo(map);

// drawing and animation (TypeScript)
public onDrawLayer(info) {
    // quick test, this just draws a red dot that blinks
    this.info = info;
    var data = [[0,0]];
    var ctx = info.canvas.getContext('2d');
    ctx.clearRect(0, 0, info.canvas.width, info.canvas.height);
    ctx.fillStyle = "rgba(255,0,0," + this.i/10 + ")";
    for (var i = 0; i < data.length; i++) {
        var d = data[i];
        if (info.bounds.contains([d[0], d[1]])) {
            var dot = info.layer._map.latLngToContainerPoint([d[0], d[1]]);
            ctx.beginPath();
            ctx.arc(dot.x, dot.y, 3, 0, Math.PI * 2);
            ctx.fill();
            ctx.closePath();
        }
    }
};

public animate() {
    // make the point blink
    if (this.up) {
        this.i++;
        if (this.i >= 10) this.up = false;
    }
    else
    {
        this.i--;
        if (this.i <= 1) this.up = true;
    }

    // animate:
    this.mapCanvasLayer.drawLayer();
    window.requestAnimationFrame(this.animate.bind(this));
}

Попытки расширений:

Еще не пробовал:

У меня такое ощущение, что это происходит из-за того, что событие перетаскивания или перевод координат (latLngToContainerPoint) не обрабатываются должным образом, но я понятия не имею, почему. В примерах, доступных для Leaflet.CanvasLayer , перетаскивание анимированной карты работает нормально. Есть идеи, что не так с этим кодом? Спасибо за вашу помощь!

Редактировать

Смотрите комментарии: заменил звонок, как показано ниже:

// var dot = info.layer._map.latLngToContainerPoint([d[0], d[1]]);
var dot = info.layer._map.latLngToLayerPoint([d[0], d[1]]);

Теперь точка движется правильно. Однако, когда я отпускаю кнопку, она теперь сдвигается в положение относительно контейнера, то есть на то же расстояние границ окна, но с неправильными координатами (неправильное расположение на карте).

Если я сейчас сделаю это:

public onDrawLayer(info) {
    this.info = info;
    var ctx = info.canvas.getContext('2d');
    ctx.clearRect(0, 0, info.canvas.width, info.canvas.height);

    const fillStyleLayer     = "rgba(255,0,0,1)"; // red: layer
    const fillStyleContainer = "rgba(0,0,255,1)"; // blue: container

    var layerPoint     = info.layer._map.latLngToLayerPoint([0,0]);
    var containerPoint = info.layer._map.latLngToContainerPoint([0,0]);

    // this.dot = (this.dragging)
    //     ? info.layer._map.latLngToLayerPoint([0,0]);
    //     : info.layer._map.latLngToContainerPoint([0,0]);

    ctx.fillStyle = fillStyleLayer;
    ctx.beginPath();
    ctx.arc(layerPoint.x, layerPoint.y, 3, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();

    ctx.fillStyle = fillStyleContainer;
    ctx.beginPath();
    ctx.arc(containerPoint.x, containerPoint.y, 3, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();
};

public animate() {
    this.mapCanvasLayer.drawLayer();
    window.requestAnimationFrame(this.animate.bind(this));
}

Точка слоя (красная) перемещается правильно при панорамировании, но затем перемещается в неправильное место. Точка контейнера (синяя) перемещается слишком сильно при панорамировании, но затем возвращается в правильное положение ...: (

1 Ответ

0 голосов
/ 02 августа 2019

Немного опоздал к игре, но переключение на L.canvasOverlay () сработало для меня. Вот отличный пример библиотеки в действии

http://bl.ocks.org/Sumbera/11114288

...