How to move popup div along with marker in leaflet - css

I have a map drawn using leaflet. In that map I have drawn several markers at different locations. On clicking the marker I am creating a popup div that shows some message.
I have the code:
markers.on("click", function(d) {
div.html("This is Some info").style(
"left", (d3.event.pageX) + "px").style(
"top", (d3.event.pageY - 80) + "px");
}
So the div appears in the location where I clicked i.e. at the location of the marker.
Now if I drag the map the markers move along with the map but the div remains at the same location.
How can I change the style of div with drag event so that the div also moves along with marker?
I was trying the following code in the drag event method:
if(d.code==clickedcode)
{
console.log((map.latLngToLayerPoint([ d.lat, d.lon ]).x) + "px , "
+(map.latLngToLayerPoint([ d.lat, d.lon ]).y - 80) + "px");
div.style["left"]=(map.latLngToLayerPoint([ d.lat, d.lon ]).x) + "px";
div.style["top"]=(map.latLngToLayerPoint([ d.lat, d.lon ]).y - 80) + "px";
}
But it still shows the same pixel position as previous time.

You could try using the map 'drag' event to calculate the shift and then apply that to your div location. Something along these lines...
var startCoords;
var startLat;
var startLng;
var movedCoords;
var shiftLat;
var shiftLng;
map.on('dragstart', function() {
startCoords = map.getCenter();
startLat = startCoords.lat;
startLng = startCoords.lng;
console.log("STARTED FROM: " + startLat + "," +startLng);
});
map.on('drag', function() {
movedCoords = map.getCenter();
shiftLat = startLat - movedCoords.lat;
shiftLng = startLng - movedCoords.lng;
console.log("Shifted: " + shiftLat + "," + shiftLng);
//apply shift to custom div here...
});

Related

D3 Collapsible child nodes going around root node in circles

how can i space the Collapsible tree nodes in circles going around the root node?Example of picture below.second image what i currently have now.
i know it has something to do with the X and Y position in this method.But i just can't figure out how.
original code i got it from Original code here
function update(source) {
// Assigns the x and y position for the nodes
var treeData = treemap(root);
// Compute the new tree layout.
var nodes = treeData.descendants(),
links = treeData.descendants().slice(1);
debugger
// Normalize for fixed-depth.
nodes.forEach(function (d) {
//i know i have to do something here
d.y = d.depth * 180;
});
// Transition to the proper position for the node
//then it will update the transform and translate
enter code here
nodeUpdate.transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + d.y + "," + d.x + ")";
});
solved.this is my outcome.
instead of using translate for my rotating.i use rotate class with transform.

Why aren't my Google maps overlays not drawn on first update?

I was following the Google-maps overlay example and have modified it to fit my needs. This is my new draw prototype for USGSOverlay:
USGSOverlay.prototype.draw = function()
{
//need to use projection to get image position from latLng to Px
var overlayProjection = this.getProjection();
var mapPos = new google.maps.LatLng(this.y_, this.x_);
var posInPx = overlayProjection.fromLatLngToDivPixel(mapPos);
//calculate the size in current zoom
//imageScaleFactor is a global variable placed on top in document
var dx = Math.abs(this.img_.naturalWidth * Math.pow(2, map.getZoom()) * imageScaleFactor);
var dy = (dx / this.img_.naturalWidth) * this.img_.naturalHeight;
// Resize the image's div to fit the indicated dimensions.
//places the image so that the given input (x_, y_) is in the center
var div = this.div_;
div.style.left = posInPx.x - dx / 2 + 'px';
div.style.top = posInPx.y - dy / 2 + 'px';
div.style.width = dx + 'px';
div.style.height = dy + 'px';
};
When I load the page for the first time my overlays would not appear until I translated the map for a long enough distance or zoomed in/out.
The problem is that I the operations this.img_.naturalWidth and this.img_.naturalHeight was taking too long and didn't give a value in time for the map to be initiated where I assume it runs the draw function for each overlay once.
My solution was to add a listener for the image in the onAdd prototype for USGSOverlay:
var thisOverlay = this;
//draw country when image is finished loading
this.img_.onload = function(e){
thisOverlay.draw();
}
This will call the draw function of the overlay once it's image is loaded.
The thisOverlay variable is needed because the object itself cannot be accessed from the onload function as far as I can tell.

How to move CSS background based on cursor/finger position without using background-position property?

I'm working on a small app where the user move the background with his mouse or his finger on the screen.
You can find a demo here: http://kaleidoscope-experiment.herokuapp.com/
The background-position is defined by the position of the cursor/finger using this kind of code:
// mobile
position = e.touches[0].pageX + 'px ' + e.touches[0].pageY + 'px';
// desktop
position = e.pageX + 'px ' + e.pageY + 'px';
However, I have significant lags on mobile and tablet and the background is "clipping".
Do you know if there is any alternative to background-position (transform?), to move the background based on the cursor/mouse position?
If you want to roll your own just use a combination of the jQuery mousemove function in combination with CSS3 transforms. Something along the lines of this:
$( "#target" ).mousemove(function( event ) {
var msg = "Handler for .mousemove() called at ";
msg += event.pageX + ", " + event.pageY;
console.log( "<div>" + msg + "</div>" );
$("#movingobject").css('transform', 'translate(' + event.pageY /4 + 'px,' + -event.pageX /4+ 'px)');
});
Here is the reference fiddle that i got from stackoverflow
http://jsfiddle.net/ZmZhw/
There are number of js plugin that are available which will give u some smooth transition and performance also.

How to avoid jsPlumb connectors break off while dragging the dynamically created divs

I am new to jsPlumb. I have created dynamic divs by reading a table from database and I have connected these divs by using JsPlumb connectors. The divs have been made draggable. The connectors are showing up correctly when the page loads, but when I drag or move the divs the connectors breaks off and moved to top. If I create a static divs which are not coming from database then the connectors are working perfectly and when I drag/move the divs then the connectors are also moving along the divs connected to source and target divs.
After doing a complete search on google and by going through jsPlumb documents, I did not find any solution for this.
Can anyone tell me as what should be done to have the connectors stay connected to source and destination even when we drag or move the divs.
Here is what I have done:
JsPlumb Code for one connection:
jsPlumb.ready(function() {
jsPlumb.connect({
source: "FDiv1",
target: "IDiv1",
connector: ["Flowchart"],
anchors: ["RightMiddle", "LeftMiddle"],
paintStyle: {
lineWidth: 2,
strokeStyle: "rgb(189, 11, 50)",
outlineColor: "#666",
outlineWidth: 1
},
hoverPaintStyle: { strokeStyle: "#7ec3d9" },
detachable: false,
endpoint: "Blank",
endpointsOnTop: false,
deleteEndpointsOnDetach: false,
endpointStyle: { fillStyle: "#a7b04b" },
overlays: [ "Arrow" ]
});
jsPlumb.draggable($(".bg"));
});
I have hardcoded the source and target here which later I should be getting these dynamically to connect all other divs.
Here is the dynamic divs code in code behind.
foreach (DataRow dt in ds.Tables[0].Rows)
{
HtmlGenericControl myDiv = new HtmlGenericControl("div");
HtmlGenericControl myDiv2 = new HtmlGenericControl("div");
//********Source Div**************
myDiv.ID = "FDiv" + j;
myDiv.Attributes.Add("class", "bg");
myDiv.Style.Add(HtmlTextWriterStyle.MarginLeft, "30px");
myDiv.Style.Add(HtmlTextWriterStyle.MarginTop, top + "px");
myDiv.InnerHtml = "Filename: " + dt["Column1"].ToString() + "<br>" + myDiv.ID;
PlaceHolder1.Controls.Add(myDiv);
//************Target Div****************
myDiv2.ID = "IDiv" + j;
myDiv2.Attributes.Add("class", "bg");
myDiv2.Style.Add(HtmlTextWriterStyle.MarginLeft, "260px");
myDiv2.Style.Add(HtmlTextWriterStyle.MarginTop, top + "px");
myDiv2.InnerHtml = "Filename: " + dt["Column2"].ToString() + "<br>" + myDiv2.ID;
PlaceHolder1.Controls.Add(myDiv2);
top = top + 140;
j = j + 1;
}
Instead of making the DIV draggable as jsPlumb.draggable($(".bg"));
Try making the DIV draggable during its creation.
i.e.
Source Div
myDiv.ID = "FDiv" + j;
myDiv.Attributes.Add("class", "bg");
myDiv.Style.Add(HtmlTextWriterStyle.MarginLeft, "30px");
myDiv.Style.Add(HtmlTextWriterStyle.MarginTop, top + "px");
myDiv.InnerHtml = "Filename: " + dt["Column1"].ToString() + "<br>" + myDiv.ID;
jsPlumb.draggable($('#FDiv' + j)); // make it draggable
PlaceHolder1.Controls.Add(myDiv);
`
||y for target DIV
I had a similar issue with dynamically created divs and solved it by not using jsPlumb.draggable(element) but instead jQuery and jsPumb.repaint(element) as follows (the example is a bit overkill with the use of repaint but you get the picture):
element.draggable({
step: function () {
jsPlumb.repaint(element);
},
drag:function(){
jsPlumb.repaint(element);
},
stop:function(){
jsPlumb.repaint(element);
}
});
Hope this helps you.

Google Maps API V3 - Custom Tiles

I am currently working on Google Maps API V3 over here
If you zoom between 21 to 23, there will be an image overlay on the map. The image takes too long to load and I have decided to break it into different tiles for easier loading. I am using Automatic Tile Cutter to cut the image into tiles.
I have problems with the script;
var OrgX = 31551; // the Google Maps X value of the tile at the top left corner of your Photoshop document
var OrgY = 50899; // the Google Maps Y value of the tile at the top left corner of your Photoshop document
First question How do you find the values of X and Y from the photoshop document?
Let say if I manage to solve the first question.
Second question Is the below code correct to display the tiles depending on the zoom level? Or am I missing any codes?
var BuildingsLayer = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://search.missouristate.edu/map/tilesets/baselayer/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
isPng: true
});
map.overlayMapTypes.push(BuildingsLayer);
Instead of using Automatic Tile Cutter, I used and recommended MapTiler.
Not only it slices the image into tiles and it also generates out a javascript tiles script to use it.
However, the script is written in v2. You can edit the codes according:
v3 tiles script
var maptiler = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return zoom + "/" + coord.x + "/" + (Math.pow(2,zoom)-coord.y-1) + ".png";
},
tileSize: new google.maps.Size(256, 256),
isPng: true
});
var map;
function initialize() {
map = new google.maps.Map(document.getElementById("map_canvas"));
map.setCenter(new google.maps.LatLng(36.07, -112.19));
map.setZoom(11);
map.setMapTypeId('satellite');
map.overlayMapTypes.insertAt(0, maptiler);
}
Credits

Resources