According to the documentation, I should be able to configure the size of my OpenLayers popup by declaring an OpenLayers.Size object in the FramedCloud constructor:
this.popup = new OpenLayers.Popup.FramedCloud('featurePopup',
this.options.feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(80, 60),
html,
null, true, this.onPopupClose
);
map.addPopup(this.popup, true);
Currently the popup that is rendered is autosized no matter what dimensions I use in the constructor.
I've tried manually setting the autosizing attribute of the FramedCloud to false as well as manually adjusting the css styling for the popup without achieving the results I need.
I checked and found some similar issues in the OpenLayers 2.11 issues list, but I haven't found a workaround. Any ideas?
this.popup.autoSize = false;
Add this instruction before the addPopup().
Not sure how helpful this will be for others, but for this particular example, scrollbars were being rendered as a result of a floated div at the bottom of the dialog. By updating the css I was able to draw clean autosized popups without having to calculate custom dimensions.
I got the same problem and the only workaround I found is to use for instance AnchoredBubble.
Related
I am trying to implement a pop-up context menu in GoogleMaps. The best of the Google search results I found was this 2012 StackOverflow post
Google Map V3 context menu
(of four examples given at top, two URLs no longer work - but some additional options are given in later comments)
I investigated four code options mentioned there, deciding that the Pearman code, as referenced in
http://googlemapsmania.blogspot.com/2012/04/create-google-maps-context-menu.html
would be best for my case. However, when I implemented it I discovered a problem - which I then determined also occurs in his original example
http://code.martinpearman.co.uk/googlemapsapi/contextmenu/1.0/examples/advanced_example.htm
when one knows what to look for. (This also occurs for a later fork of the original code that I found). All works as expected so long as the map is not moved, with the pop-up menu position being altered by the location of the mouse click such that the entire menu is always visible within the map area. BUT if the map is moved, then the popup can be cutoff, per the bottom left corner in the example below (in which I first moved Norwich into the corner, then right-clicked on it)
Looking into the code, I see it uses GoogleMaps Overlay. Reading up a bit on that, I get the impression that "something" needs to be done/updated when an overlay is moved. But I am beyond my knowledge level and ability to fully understand what I am reading, so am hoping to find some help/insight here. Hoping to figure out a general solution to also help others who implement Pearman's code.
SOLUTION FOUND
Lots of searching and testing and false turns while working on this, but finally got a solution - of course it seems "obvious" after one finally sorts out what is going on.
Short answer: values returned by GM Overlay "fromLatLngToDivPixel" function represent the "GM DIV" and hence location on the GM map whereas "fromLatLngToContainerDiv" values represent the "map_canvas DIV" and hence the observed map boundary. So the actual placing of the menu must be based upon values returned by "fromLatLngToDivPixel" but testing its visibility within the map_canvas DIV must be based upon values from "fromLatLngToContainerDiv". Sometimes values returned by the different functions are identical but sometimes not - the former seems to occur when the map is static whereas the latter can occur when the map is moved/dragged.
Long answer:
The relevant part of the original Pearman code is, where "left" and "top" are later used in CSS styling of the menu, to set its position:
var mousePosition=this.getProjection().fromLatLngToDivPixel(this.position_);
var left=mousePosition.x;
var top=mousePosition.y;
if(mousePosition.x>mapSize.width-menuSize.width-this.pixelOffset.x){
left=left-menuSize.width-this.pixelOffset.x;
} else {
left+=this.pixelOffset.x;
}
if(mousePosition.y>mapSize.height-menuSize.height-this.pixelOffset.y){
top=top-menuSize.height-this.pixelOffset.y;
} else{
top+=this.pixelOffset.y;
}
I found the following helpful comments regarding "fromLatLngToContainerPixel" in How to call fromLatLngToDivPixel in Google Maps API V3? , which led me to my fix
... This works perfectly for me initially, but if I pan the map the
pixel positions are not updated. ...
... using fromLatLngToContainerPixel instead of fromLatLngToDivPixel
solved my issue with pixel positions not updating after panning the map.
Roger Ertesvag
Looking at values returned by "fromLatLngToDivPixel", they were sometimes not valid for the map_canvas DIV containing the map (i.e. were sometime larger than the size of that DIV), whereas "fromLatLngToContainerPixel" DID produce apparently valid values. But the seemingly obvious "fix" of simply replacing "fromLatLngToDivPixel" with "fromLatLngToContainerPixel" often produced much weirdness, with the menu not appearing.
I now gather that the "mousePosition" values returned by "fromLatLngToDivPixel" are valid for the location within the "GoogleMaps DIV" (still unclear exactly what that is) but are not appropriate for the map_canvas DIV. Thus my "fix" was to use values from "fromLatLngToDivPixel" for the "base" menu location but use values from "fromLatLngToContainerPixel" to test and alter its display within the map_canvas DIV.
Specifically, instead of the original I'm now using the following code and it is working successfully.
var mousePosition=this.getProjection().fromLatLngToDivPixel(this.position_);
var left=mousePosition.x;
var top=mousePosition.y;
// my fix below, adjusting location based on nearness of map area boundary
var containerPosition=this.getProjection().fromLatLngToContainerPixel(this.position_);
if(containerPosition.x>mapSize.width-menuSize.width-this.pixelOffset.x){
left=left-menuSize.width-this.pixelOffset.x;
} else {
left+=this.pixelOffset.x;
}
if(containerPosition.y>mapSize.height-menuSize.height-this.pixelOffset.y){
top=top-menuSize.height-this.pixelOffset.y;
} else {
top+=this.pixelOffset.y;
}
PS: as a note to someone wanting to use the Pearman code for their context menus, I am actually using code (now altered) from a fork based upon it
https://github.com/knezmilos13/google-maps-api-contextmenu
The fork adds the ability to have global class names for the menu items, but that is not why I'm using it. For me, the original Pearman code sometimes produced a "sticky" menu, i.e. the menu remained displayed after it should be closed, especially on first usage of a menu, but that behaviour did not occur using the forked code. Don't know the reason for the difference, did not investigate further.
I have a fixed header that I would like to add a dynamic blur as the user scrolls down the page. I learned that the filter: blur(10px) only works for elements within the applied div.Could anyone point me in the right direction?
Updated: What I want to do is make anything that is underneath my fixed header appear blurred, not the actual header itself. I think I would have to make parts of the div under the header blurred rather than the whole div to achieve this effect.
Yes, add dynamicaly a classname with jquery.
http://api.jquery.com/scroll/
$(window).scroll(function() {
$( "#tag" ).addClass( "blurredclass" );
});
You can define a variable within scroll function to check offsetTop position, so you can add blurred class after you reach your position
var screenTop = $(document).scrollTop();
Edit: you can preview typical solution on JSFiddle
http://jsfiddle.net/x2N3N/1/
Edit2: if you want to blur text below some position while scrolling:
http://jsfiddle.net/x2N3N/2/
Edit3: variant with blurred header:
http://jsfiddle.net/x2N3N/3/
There is another option to help you solve your problem. If you want to blur the header background while scrolling the page (e.g. in iOS7 on iphone) the solution exists:
Using experimental methods:
http://codepen.io/FWeinb/full/Dfoaw
But problem is compatibility and speed:
Chrome 29+ (enable 'experimental-webkit-features'/'enable-experimental-web-platform-features')
Safari 6.1 Seed 6
iOS7 - slow
Next method is to blur rendered html in canvas
More info and example: http://blurpopup.labs.daum.net/
run html2canvas for rendering document as an image.
Convert image to data-url string and and place it as background-image.
apply blur (-webkit-filter:blur ... )
Append the bg layer into document with position of document scroll offset.
You can find html2canvas here: http://html2canvas.hertzen.com/ (it's a simple js library)
I've done complete live example with basic usage:
http://www.24development.cz/examples/blurred-header/
There are some limitations with html2canvas rendering, but for basic idea there is the point.
I'm using Isotope (http://isotope.metafizzy.co). Testing the reLayout method by using the example provided here (http://isotope.metafizzy.co/demos/relayout.html), copied the css, js to (http://punkbit.com/webzine/isotope.html) but when I click in the first element all other elements go to the first column. I wonder why this happens ?
If we do the same in the official example, it works properly, apparently!
I'd like to toggle a class in the first element and by doing that, having the other elements take the vertical space and positioned properly. I tried to change the width of the container, etc but no success!
I've also got the same issue happening with Masonry:
http://codepen.io/anon/pen/BKAdH
If clicking in the first element, it won't work. All elements will be placed in the first column.
Also tried different layout modes etc without success
Sorry,
I've found the answer:
http://punkbit.com/webzine/isotope2.html
The property "columnWidth" needs to be set.
For Masonry:
http://codepen.io/helderoliveira/pen/gwvjA
I'm having an issue with three custom controls I have created for a map application.
According to the API documentation:
The API places controls at each position by the order of an index property; controls with a lower index are placed first. For example, two custom controls at position BOTTOM_RIGHT will be laid out according to this index order, with lower index values taking precedence. By default, all custom controls are placed after placing any API default controls. You can override this behavior by setting a control's index property to be a negative value. Custom controls cannot be placed to the left of the logo or to the right of the copyrights.
Therefore, I added the three controls to the same position, giving each an index value, and expected them to fit accordingly.
When the controls are first loaded, they are on top of one another, instead of fitting to match their respective index values.
However, when I perform an action such as hovering over another default control (such as the zoom control), the custom controls appear correctly.
Here is what I have tried to fix the problem:
Setting the position of the controls in CSS (does not work since control positioning can only be custom if you wrap the controls)
Delaying the time for each control button to be added
Tried triggering mouseover actions of other controls since this manually shows the controls in the correct position
Any help or insight in appreciated. I know I mentioned wrapping the controls allows for custom position (according to here), but is there any other way I can get this to work without doing so?
My apologies, I tried uploading screenshots but apparently I am not popular enough. Here is a JsFiddle.
The JsFiddle shows how I am adding these controls only when the user has selected a specific input:
$('#toggle').on('click', function(){
if ($(this).is(':checked')){
$(pointSelDiv).css('display', 'block');
$(polySelDiv).css('display', 'block');
$(circSelDiv).css('display', 'block');
}else{
$(pointSelDiv).css('display', 'none');
$(polySelDiv).css('display', 'none');
$(circSelDiv).css('display', 'none');
}
});
Thanks again!
This is happening because Google Maps API needs to know the width and the height of your control elements to know where to position them - when the map is rendered. By initially setting them to display: none, you are hiding it from the actual layout of your page as well - it's as if the element's not there. Use visibility: hidden instead - setting the visibility to hidden will still hide the element on the screen, but it is still present in the layout. For reference: http://www.w3schools.com/css/css_display_visibility.asp
Also, I suggest rather than individually setting these CSS attributes to your custom control elements, add a class (you can do this via jquery's .addClass()) to these elements and toggle just by targeting the class. I've updated your jsfiddle here.
instead of having the containment of the draggable element around it, how can I have it inside it? So you can drag the element anywhere as long as the edges of it do not collide with the element inside of it?
One approach is to use the drag event and update the ui.position or ui.offset fields, to manually constrain the item.
Here is a jsfiddle to illustrate the concept, although this doesn't fully implement what you describe.
You could fake it by making a real containing component that restricts your draggable element as if it is constrained by the smaller element. You would just have to make the dimensions of the real container like this:
Container.height = (Draggable.height - Restrict.height) + Draggable.height
Container.width = (Draggable.width - Restrict.width) + Draggable.width
Then, you would also need to counter the dragging motion so that the contained restriction element doesn't seem to move when the draggable element moves. Either that or the immobile section could be a floating div.
Building upon #RustyTheBoyRobot's answer you could also accomplish in CSS alone if you have known dimensions of your draggable.
Live Example - jsbin.com/agovex
The obvious downside of this is if you want to reuse this in multiple situations it's not going to work because the values are hardcoded in CSS. But if you only need it for one thing with known dimensions I find the CSS only approach simple and elegant. There's only one line of JavaScript to create the draggable.
If anyone else is interested in this, using Rusty's code and logic here's a JSfiddle link.