I'm using Leaflet Draw to draw rectangles on a Leaflet map. The rectangles get added to a FeatureGroup once they are created, and their styles are updated based on their size. For example, the rectangles are filled red if their area exceeds a certain threshold and green if their area is within the threshold.
I'm leveraging the "draw:created" callback to inspect the completed rectangle's size. I'm also able to update the rectangle's style during editing by leveraging the "draw:editresize" and "draw:editmove" callbacks. By doing this, users can easily see if their rectangles fall within the correct area requirements while they are resizing them.
Here is my problem: I haven't been able to find a callback that allows me to style the rectangle during its initial creation. Have I overlooked a callback? I've tried all of the logical ones from the doc's: https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw-event.
There's not really any code to show other than the following event handlers, which currently work while editing a rectangle.
this.map.on('draw:editmove', function (e) {
self.setROIStyle(e);// works
});
this.map.on('draw:editresize', function (e) {
self.setROIStyle(e);//works
});
Thanks,
Ray
Related
I am coding in JavaScript using the Google Maps API, and I was curious if there was a way to set the priority of what polygon array info window is shown when I click on an area. I have two polygons that are overlapping, and I need to control which info bubble appears when you click on the overlapped area. Thank you!
The click will be triggered on the most top Polygon.
The order of the polygons usually depends on the order in which they have been added to the map(when the map-property has been set) or by setting a custom zIndex-property.
So when you want to define a priority you must define the zIndex for the Polygons.
When you want to be able to click on each polygon(and each part of each polygon) there is a simple approach:
Observe the mouseover of the polygons and set the zIndex of the hovered polygon to a value higher than the zIndex of the other polygons. This will bring the polygon into front and you now may also click on the previously covered area.
You may implement this by extending the polygon-prototype:
(function(){
var a=z=0;
google.maps.Polygon_=function(opts){
this.setValues(opts)
google.maps.event.addListener(this,'mouseover',function(){
this.set('zIndex',++z);
});
google.maps.event.addListener(this,'rightclick',function(){
this.set('zIndex',--a);
});
};
google.maps.Polygon_.prototype = google.maps.Polygon.prototype;
google.maps.Polygon = google.maps.Polygon_;}
)();
Demo: http://jsfiddle.net/doktormolle/wznd5nsy/
(Use rightclick to send a polygon to back, e.g. when it completely covers another polygon).
Is it possible to move any elements added using
chart.renderer
as we update the range or the navigator handles?
There is a square in this fiddle. Can we shift its position as we update the navigator?
Or can you point me to the function in the source code that can help?
Thanks
Update: i want to draw trendlines/ fibonnacci retracements etc. based on user events. Currently, i draw & drag the lines using chart.renderer until the mouseup event, calculate the x,y values of the end points, delete the rendered lines & then add new series which visually imitate those rendered lines. This is surely not the best solution. The issue is how to remember the position of the user selection & show/scale the same only when those lines are in the visible range.
So i am wondering if we could directly use some internal "scaling" function that calculates the visible points of the series based on the current extremes.
Rendered object's position is basend on pixels, so when you use navigator, pixels "are the same" so object stay in the same position. But you can catch navigator "sliding" by setExtremes and aftersetExtremes functions and then move element by translate().
Simple example of using translate():
obj.translate(120,20);
http://jsfiddle.net/Ne7QV/1/
Only what you need is common both elements, according to your expectations.
I would like to be able to fitBounds to a feature when you click on it, but when it zooms in I'd like it to take into account a control layer that will appear once zoomed in, and zoom in but just about 150px to the left. Currently I can accomplish this with the following code, but unfortunately it's not a smooth zoom because my current method will zoom using fitBounds and then once zoomed it uses panBy to pan 150px to the left. This wouldn't be so bad if the panning was smooth, perhaps maybe after a 250ms wait. Ideally I would like to be able to do some math on the bounds passed to the fitBounds method to simply account for the 150px shift to the left.
Here is an example of what I currently have working.
Here is a simplified version of the code I'm using: (you may click here for a fully working version with all of the source code)
when you click
function clickFeature(e) {
var layer = e.target;
map.fitBounds(layer.getBounds());
}
map on zoomEnd:
map.on({
zoomend: function() {
map.panBy([150, 0]);
}
});
So, I've achieved the desired function, but it's just not smooth.
Is there a way to just do some math on the bounds that we're getting for the clicked feature so that when we zoom we zoom into an already modified coordinate, thus eliminating the two-step animation process?
First of all, you can control the animation using pan options. This could help you make the transition smoother.
You can see those here.
Second, you can calculate the offset that you need by using the conversion functions. These can be seen here.
For example, you could do something like (off the top of my head) use getBoundsZoom for the map object on the polygon bounds to figure out your future zoom, then use that zoom in the project function with the polygon and create a new LatLngBound from the polygon bound that is slightly offset.
Hope this helps!
I had this same issue, and if was easier than I had thought!
You can set padding on the fitBounds method (and all the pan/zoom methods for that matter)
http://leafletjs.com/reference.html#map-fitboundsoptions
so:
map.fitBounds(layer.getBounds(),{paddingBottomRight:[150,0]});
I'm working on a script to do several things. In a nutshell, here's what it needs to do:
Read the coordinates from a page and be able to pop up a box within a specific region.
The pop up box needs to be able to follow the mouse around.
I need to be able to modify the box to look however I want (I was thinking a div container that is set to display:hidden, and then the JS sets the display to block when your mouse is in the specified region).
I need to be able to modify it easily (aka, add and subtract objects and coordinate sets)
I was originally using HTML maps (), and that worked great, until I resized my browser, and the div that I had following the mouse no longer lined up correctly. Something about the offset not working correctly, and I couldn't get it to work correctly, so I switched to an HTML canvas.
And now I've got the coordinates in the canvas correctly, I just can't figure out how to get something to pop up when the mouse is inside of a certain section. Here's my current code:
function drawLines(numbers, color){
//poly [x,y, x,y, x,y.....];
var poly=numbers;
context.fillStyle = color;
context.beginPath();
context.moveTo(poly[0], poly[1]);
for( item=2 ; item < poly.length-1 ; item+=2 )
{context.lineTo( poly[item] , poly[item+1] )};
context.closePath();
context.fill();
}
I've got each region inside of an array, which I then pass to the function one by one. The color was a test, and I can easily get each region to show up as a specified color, but that doesn't solve my problem. Any ideas? Thanks!
Seems strange to jump to canvas over a style issue, but ignoring that...
You could bind mousemove events on the canvas element and then do hit tests on your region to see if the mouse is inside the region.
Doing the hit test efficiently might be tricky depending on the number of regions your testing, but it's definitely doable.
The canvas is just like any other block level element, so the same events apply and are bound in the same way.
Here's one example of mouse events interacting with canvas. In this example, the events are bound to the document, but similar ideas apply.
http://dev.opera.com/articles/view/blob-sallad-canvas-tag-and-javascrip/
I'm writing drag & drop functionality in my HTML5 Canvas application and am wondering how to detect if I'm clicking on a shape other than a rectangle or square, in which case I would do something like this inside of my 'mousedown' event handler:
if (evt._x > 13 && evt._x < 202 .... ) {}
I don't see how to easily do something like that with an arc like this:
ctx.arc(25, 25, 20, 0, (Math.PI/180)*360);
I hope that is clear, thank you in advance.
Just use isPointInPath, which checks if a given point is within the current drawing path. If you're drawing multiple shapes to the canvas, than a good technique is to associate each of your shapes with a "hidden" canvas, draw each path to its respective canvas, than test isPointInPath against each of these, offsetting the destination/mouse coordinates as needed. Theres no reason to resort to your own calculations for this.
First you check if the click is within a shape's bounding box (the smallest rectangle which fully encloses the shape). If it is, then you do the more complex math to determine if the click is within the shape itself. You'll have to implement this math yourself as I don't think there's anything built-in for it.
You'll get the formula you need here and also in Polygon article of Wikipedia.
This may sound stupid, but you can use <area> tags inside a <map> over an <img> to create interactive polygonal shapes. They have their own onclicks/mouseovers/etc. already implemented by all browsers.