Guide to Moving Animations Smoothly When Dragging the Map in Leaflet's CanvasLayer

Attempting to incorporate a Canvas layer on top of a Bing TileLayer using the provided extensions. Furthermore, I aim to animate the canvas drawing utilizing RequestAnimationFrame. The complication arises when dragging as the point moves further than intended (refer to video). However, upon completion of the movement, it reverts to the correct position.

https://i.sstatic.net/auZqX.gif

I have experimented with various methods, including inheriting CanvasLayer and overriding render() or setting a delegate, but the outcome remains consistent.

Below is the relevant segment of the code:

// 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));
}

Attempted Extensions:

Yet to be Tested:

It seems likely that the issue lies within either the dragging event or the coordinate translations (latLngToContainerPoint) not being handled correctly, although the reason is unclear. In the available samples for the Leaflet.CanvasLayer, dragging an animated map appears to function properly. Any insights into what may be wrong with this code? Thank you for your assistance!

Edit

Refer to comments: updated the call as follows:

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

The point now moves accurately. Nevertheless, upon releasing the button, it shifts to a position relative to the container, meaning it maintains the same distance from the window borders but features incorrect coordinates (misplaced on the map).

If I implement the following:

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));
}

The layer point (red) moves appropriately during panning but then shifts to an incorrect location. The container point (blue) moves excessively during panning but eventually returns to the correct position... :(

Answer №1

Although I arrived a little late to the party, making the switch to L.canvasOverlay() proved to be the solution for me. Check out this fantastic demonstration of the library in action!

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can you explain how to retrieve the header value from ng-table?

Is there a way to retrieve the table header for each column from JavaScript? When I call tableTest, it only returns data of each row, not the header names like 'name' and 'description'. Is there a method like tableTest.data-title to acc ...

Specify that a function is adhering to an interface

Is there a way in Typescript to ensure that a function implements a specific interface? For example: import { BrowserEvents, eventHandler, Event } from './browser-events'; export function setup(){ const browserEvents = new BrowserEvents(); b ...

Enable users to handle the version of a dependency in an npm package

As I develop a module that relies on THREE.js, I am exploring the most effective method to include THREE as a dependency and ensure accessibility for both the module and its users. My goal is to provide users with access to the THREE library within their p ...

Steps for transforming Dec 2 1991 12:00AM into 12/02/1991

const dobString = "Dec 02 1991 12:00"; const newDate = dobString.substring(0, dobString.length - 6); const birthDate = $filter('date')(new Date(newDate), 'mm/dd/yyyy'); ...

Select the anchor attribute value of tabs using jQuery

After upgrading from jQuery 1.7 to 1.9, we encountered an issue with one of our functions no longer working. Our previous code used to retrieve the value of the anchor tag in the currently selected tab. select:function(event,ui) { var messageId=$(ui ...

Access the URL or link in an email using Chrome, as opposed to the default browser, IE8

I have an application that sends out an email with a URL link. When the link is clicked, it opens a new tab in the browser. Currently, the application works fine on Chrome but is not compatible with IE8. However, the client's machine has IE8 as the ...

Printing a modified div element that was created using jQuery on an ASP.NET MVC webpage after the initial page has finished loading

In my view, there is a div that holds multiple tables generated based on the model. Each row in these tables contains fields that can be edited using TextBoxFor. Through jQuery, rows can be moved between tables and new tables can be created dynamically wit ...

Using specific delimiters in Vue.js components when integrating with Django and Vue-loader

While working on my Django + Vue.js v3 app, I came across a helpful tool called vue3-sfc-loader. This allows me to easily render .vue files using Django, giving me the best of both worlds. The current setup allows Django to successfully render the .vue fil ...

Utilizing AngularJS to invoke an ng-controller within a nested controller structure

Take a look at this sample code from the cshtml file: <div> <button type="button" ng-click="recalcButton()">Recalc Button</button> </div> <div ng-controller="appealPartialController"> < ...

Exploring recursive looping within a directory using Emscripten's File API

Is there a way to iterate through files in a folder using Emscripten? For example, I have created a folder called '/res' (FS.mkdir('/res')) and added some temporary files and subfolders inside it. How can I go about looping through th ...

JS Code for Optimal Viewing on Mobile Devices

I'm struggling with creating 3 image columns in 2 columns on mobile. It seems like there is a JS issue related to the minslide:3 and maxslide:3 conditions... When viewed on mobile, it's displaying 3 slides instead of 2. How can I adjust it to sh ...

What is the best way to refresh flexslider after it has been updated via AJAX?

At first, my slider is functional upon loading the page. However, after making an ajax call and receiving new slides to populate the slider, it becomes deactivated (as expected) https://i.sstatic.net/LC0yG.png Is there a method to reinitialize the flexsl ...

My function won't get called when utilizing Angular

My Angular code is attempting to hide columns of a table using the function shouldHideColumn(). Despite my efforts, I am unable to bind my tags to the <th> and <td> elements. An error keeps popping up saying Can't bind to 'printerColu ...

What are some techniques for creating an HTML element that remains fixed on the page after scrolling past a certain height, even though it is originally part of

I am trying to achieve a specific effect with a <section></section> element on my web page. Once the user scrolls past the section, I want it to remain fixed at the top of the screen even as they continue scrolling downwards. This is in an Ang ...

The custom error page in NextJS is failing to display

In my custom pages/404.ts file, I have coded the following: export default function NotFound() { return <h1>404 - Page Not Found</h1> } Additionally, there is another page that displays a 404 error when the organization is null: import Error ...

When I try to access localhost, it directs me to http://localhost:3000/myprofile%20 instead of localhost:/3000/myprofile

Every time I try to log into my profile page with the correct login credentials, I get redirected to http://localhost:3000/myprofile%20, but then receive a 404 error. This is what my code looks like: // Login Route router.post('/login', functi ...

Customizing Drop Down Button in React Material-UI with Conditions

Trying to figure out how to dynamically populate the second MUI dropdown based on the selection from the first dropdown. Currently, I have both dropdown lists hardcoded. const [queryType, setqueryType] = React.useState(''); const [subCategory, se ...

Scrolling with jQuery just got a sleek upgrade with our new

Can anyone suggest a jQuery scrollbar that resembles the clean black bar found on the iPhone? I need a simple design without visible up or down buttons. Many scripts I came across offer more features than necessary for my project. My div element has a fi ...

Updating the parent's data by modifying data in the child component in VueJS

When I use multiple components together for reusability, the main component performs an AJAX call to retrieve data. This data is then passed down through different components in a chain of events. <input-clone endpoint="/api/website/{{ $website->id ...

Ways to enhance the appearance of the parent element when the radio button is clicked

Hey there! So, I have a situation where I'm working with two radio buttons and I want to apply certain CSS styles to the parent box (<div>) when a radio button is selected (checked). Here's how I want it to look: box-shadow: 0 0 5px #5cd05 ...