Three.js layer for leaflet - javascript

I am currently trying to build an overlay layer for leaflet. The overlay is supposed to display 3D contents (e.g. buildings). However, I have trouble with keeping the movements on the leaflet map in sync with the ones in the scene in the overlay.
So far the canvas is as large as the map container and it will always overlay the map (like a position: fixed). In order to move around when the user is panning on the map I want to move the camera in the scene (instead of moving all geometries around). For position I use the distance from lat:0, lng:0 as THREE seems to struggle with fractal positions (e.g. when using decimal gps coordinates). Unfortunately I am struggling to find the correct formula to get the correct positions for the camera (x,y,z).
My attempt so far:
https://jsfiddle.net/hg474d6r/7/ (the _handleMove function is the relevant one)
The black dot is the center and for your reference. The red dot should remain static - relative to the map - which it doesn't.
So is there just a small issue in my formula/"calculations" or will this approach not even work at all?
Update: updated fiddle with progress and so on

It looks like that the Camera will points to a fixed Point.
If you move the Camera the Direction of the Camera Vector will be changed.
So You will see this Parallaxe Effekt.

Related

How to make an Infinite Html5 Canvas which can be zoomed and panned?

I was working on a real time whiteboard.
I want to create an Infinite canvas, which can be zoomed using the mouse wheel and panned using drag, using javascript.During the zoom and pan the items drawn on the canvas must also be affected. Is there a was to achieve this without using any external library?
Yes, but it'll take a bit of work. The general idea of what you'll do is the following:
You will need to keep track of the position of the "camera", as well as how close it is to the content - a zoom factor
You will need to attach event listeners to different mouse actions to cause the camera's state to change
When you drag or zoom, you will need to redraw your canvas with the new positions and sizes of all the content. Some math will have to be done to know what the new canvas content is.
There may or may not be certain performance issues you have to address if there's a lot of content on the canvas.
An alternative, possibly quicker approach, but maybe less powerful, would be to not use canvas, and use some CSS magic instead with plain HTML. The basic concept here is that you'll have a 0x0 div as your plane. That div will contain your content, which may include content such as custom SVGs. Each of its children will break out of the div, and will be positioned relative to it. When you drag, you just move the div (through transform: translate()). When you zoom, you just scale the div (through transform: scale()).
Some useful references if taking the second approach:
CSS transform - to move and scale the whiteboard
CSS position - to position content on the whiteboard, and for the general layout
CSS overflow - to crop the whiteboard
The canvas element itself won't be infinite, I guess that's clear enough. What will change when you drag and zoom is the mapping of the real coordinates of your whiteboard elements to the drawing coordinates on the canvas. There's some work to do with detecting the mouse events and doing the calculations for updating the mapping, so there are too many specifics to really put in an answer. But yes of course this is possible without an external library.
Basically canvas could not be set to infinite sized. All you can do is to draw the portion that should be visible in the canvas.
first of all you should store all the points you have drawn to an array.
whenever you pan your canvas , track the offset that you have panned. this offset values can be used to reposition your stored points in your canvas.
eg. suppose you have drawn a line from (50 , 50) to (100 , 100).
let the offsets be {x:0 , y:0}
x , y offsets shows how much x and y distances you have panned in total
then update the points by adding the offsets and redraw
https://github.com/TomHumphries/InfiniteCanvasWhiteboard
here is a simple html5 whiteboard created by Tom Humphries which has infinite zoom and pan.

How to hover areas with XY coordinates shift in MapboxGL JS?

I use hover tooltips in my map. When an area is hovered, I show a tooltip with a small XY shift to the top left corner so that the pointer of the tooltip is not covered by the mouse cursor.
When I move mouse cursor to another area, near its border, like show in the image, the area is highlighted which is under the cursor, not under the square pointer as should be.
What are options to fix this issue? In the ideal way, I would like hover effect to be applied not to the mouse cursor coordinates, but to the coordinates of some other point that is known and changes while mouse is moving.
I once had a similar problem that I tried to solve with a different approach. I wanted to calculate the centroid of the polygon and always place the marker (in your case square pointer) on the calculated position once the user hovers over the polygon.
Main problem I had was that my polygons were concave and had holes in them (you will have the same problem if you are working with country borders) so I found a good algorithm (library) that I used to do this called Polylabel.
You can read more on this topic and how the guys from MapBox used it to solve their label positioning problems on this link.
Although this is not the answer to your question I found that this solution is fast and usable but only if the relation between the zoom level and polygon surface makes sense.
If I wanted to do something like you are suggesting I would first have a default point offset and if that offset goes outside the polygon I would find the nearest point in the polygon coordinates and attach it to that point.
To do these calculations you can use turf.js library. It has the function to return boolean value if the second geometry is completely contained by the first geometry and others that can help you to find the nearest point on the polygon border. I hope this helps!

Openlayers: Why do my drawings on my image canvas layer move on zoom?

I have an OSM Layer, a static ImageLayer and a CanvasImageLayer on top. I want to draw at specific pixel positions (relative to the 0,0 origin of the canvas) icons, e.g. at position 10,10.
This works, however, I do not understand why my canvas is resized when I move and why my Icons are then at the wrong position?
Even if I calculate the positions based on the new canvas size, they move and don't stay in their position. I really would need an explanation to understand this.
I oriented myself on this ImageCanvas example.
I only found this related question, but it does not explain it, nor does it give a solution to the problem:
openlayers 3: how to draw sth using canvas.getContext('2d') on top of the map

Get Camera's Rectangle position from CesiumJS

I am having trouble to get Rectangle position of current Camera view.
I want to create a Rectangle or Wall on the same position as current Camera view (red rectangle). Is there any way to do this?
Thank you
I am not sure I understand you problem, but I think you may have luck using the the Cesium camera's computeViewRectangle function to get the approximate rectangle the camera can see.
Here is the documentation:
https://cesiumjs.org/Cesium/Build/Documentation/Camera.html#computeViewRectangle

How to detect mouseenter/mouseleave event on lots of items without slow-down

I have realy specific question about Canvas handling mouse-events.
I'm working on a isometric game, I have a displayed map with all tiles, and I want know on which one the mouse are.
On a basic isometric map it's easy to transform the position on the screen (blue on the next image) on a map position (orange) with basic affine function (ax+b, with 'a' is width_tile/height_tile and b is the current position of the map view, red line on the image)..
But I have a complication, each tile of the game have a specific elevation (displayed by red arrow on second image). So i can't use a function for each line(y)/column(x) of the map.
On the same technique I'll try to calculate if mouse position are on EACH tile one by one for EACH mouse event (move, click, ..) but I'm afraid for the heavy code : if I have a 100x100 map and I shack the mouse, I'm sure all this test will ruin the client browser..
I realy don't know how can I do it better ?!
Someone have an idea, or a tips to optimize this check ?

Categories

Resources