Bing Maps .v7 How to reference pushpins with links outside of the map? - bing-api

I have a Bing Map in which I have a set of pushpins, with InfoBoxes associated with each one. I am using v7.
I'd like have a link that is outside the map to display a particular pushpin's Infobox. How can this be done?
example code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
/* Define a style used for infoboxes */
.NSIMInfoBox
{
position: absolute;
border: solid 2px black;
background-color: White;
z-index: 1000;
padding: 5px;
width: 250px;
visibility: visible;
}
#mapDiv
{
position: relative;
top: 20;
left: 20;
width: 800px;
height: 800px;
border: solid 2px #555;
}
</style>
<script charset="UTF-8" type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0">
</script>
<script type="text/javascript" src="jquery-1.5.2.min.js"></script>
</script>
<script>
$(document).ready(function () {
getMap();
});
var pinInfobox = null;
var map;
var pin;
function getMap() {
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
{ credentials: "apikey",
center: new Microsoft.Maps.Location(45.5, -122.5),
zoom: 10,
showScaleBar: true,
mapTypeId: Microsoft.Maps.MapTypeId.road
});
// //Multiple locations
// var polygonWithPins = new Microsoft.Maps.EntityCollection();
var loc1 = new Microsoft.Maps.Location(45.5, -122.5);
var loc2 = new Microsoft.Maps.Location(45.6, -122.5);
pin = new Microsoft.Maps.Pushpin(loc1);
//Microsoft.Maps.Events.addHandler(pin, 'click', displayEventInfo);
pin.setInfoBox(new InfoBox("<strong>Pushpin Number1!</strong>"));
map.entities.push(pin)
var pin2 = new Microsoft.Maps.Pushpin(loc2);
pin2.setInfoBox(new InfoBox("<strong>Pushpin Number 2!</strong>"));
map.entities.push(pin2)
}
function InfoBox(html) {
this.div;
this.html = html;
}
InfoBox.prototype.show = function (e) {
if (this.div == undefined) {
//Create container div
this.div = document.createElement("div");
this.div.className = "NSIMInfoBox";
this.div.innerHTML = createInfoBox(this.html);
this.div.style.display = "";
var mapDiv = document.getElementById('mapDiv');
mapDiv.appendChild(this.div);
}
var pinLocation = map.tryLocationToPixel(e.target.getLocation(), Microsoft.Maps.PixelReference.control);
this.div.style.left = pinLocation.x + "px";
this.div.style.top = pinLocation.y + "px";
this.div.style.visibility = "visible";
this.div.style.display = "block";
};
InfoBox.prototype.hide = function (e) {
if (this.div != undefined) {
this.div.style.visibility = "hidden";
}
};
//Extend pushpinclass
Microsoft.Maps.Pushpin.prototype.setInfoBox = function (infoBox) {
if (typeof this.infoBox != undefined && this.infoBox != undefined && this.infoBox != null) {
this.removeInfoBox();
}
// Add handlers for mouse events
this.mouseoverHandler = Microsoft.Maps.Events.addHandler(this, 'click',
function (e) { infoBox.show(e); }
);
this.mouseoutHander = Microsoft.Maps.Events.addHandler(this, 'mouseleave',
function (e) { infoBox.hide(e); }
);
};
// Extend the Pushpin class to remove an existing InfoBox object
Microsoft.Maps.Pushpin.prototype.removeInfoBox = function () {
this.infoBox = null;
// Remove handlers for mouse events
Microsoft.Maps.Events.removeHandler(this.mouseoverHandler);
Microsoft.Maps.Events.removeHandler(this.mouseoutHander);
}
function createInfoBox(html) {
var myHtml;
myHtml = '<div style="text-align:right; margin-right: 5px;" onclick="closeInfoBox();">x</div>' +
'<div style="padding: 5px;">' + html + '</div>';
return myHtml;
}
function closeInfoBox() {
$('.NSIMInfoBox').hide();
}
</script>
</head>
<body>
<div id="mapDiv" class="map"></div>
<span class="click">click me! - HERE I WANT TO SHOW THE FIRST PIN'S INFOBOX</span>
</body>
</html>

This is how I was able to solve this problem -
Since I pushed the pins into the EntityCollection, I was able to reference the pushpin by parsing through the collection, then calling the invoke method in order to get the result I was looking for:
Sample:
var newpin = map.entities.get(i);
Microsoft.Maps.Events.invoke(newpin, 'click', '');

I haven't tried this, but I would hope it can work. Essentially you can simulate the mouse events over a pushpin object.
First, when creating a pushpin, be sure to set a class name on the resulting by setting the typeName property on the pushpin options object. This will allow you get hold of the resulting div by using the css selector #mapDiv div..
Then you can create an event and dispatch it on the div, which will indicate to the map control that it should show the information associated with the pushpin. Since you're using jQuery, I think it would be something along the lines of (in response to the click event on your link that is outside the map control):
// assuming the typeName you used was "foo"
$('#mapDiv div.foo').trigger($.event('mousemove'));
You might have to try issuing mouseover before/instead of the mousemove. Also this is a general idea of a potential approach ... hopefully it yields in a solution.

Related

Shadow DOM v1 CSS polyfill

https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom
This got me all excited I could write my own custom webpage from scratch without polymer.
Only to find out css :host for example is not working in Edge and FireFox. I can deal without html import for now until w3c figured out what they want to do with es6 modules, but each browser having their own half implemented Shadow DOM version without css is pushing my buttons.
So I still need a full polymer stack to have webcomponents in all browsers.
<script src="../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../hello-world.html">
<hello-world>Hello World Polymer 2.x</hello-world>
Does anybody know how to polyfill Edge and FireFox to have a actually Shadow DOM, not a native Shadow DOM that's pretending to be one?
This is what I tried, but I can't figure out how to tell Edge and FireFox to put their Shadow wannabe somewhere else and use the shadydom/shadycss.
https://jsbin.com/quvozo
<!DOCTYPE html>
<html>
<head>
<title>Components</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/>
</head>
<body>
<hello-world>Hello World ES2015</hello-world>
<script>
function loadScript(src, main) {
return new Promise(function(resolve, reject) {
const script = document.createElement('script');
script.async = true;
script.src = src;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
let polyfilled = false;
const loadPromises = [];
if (!('customElements' in window)) {
loadPromises.push(loadScript('https://raw.githubusercontent.com/webcomponents/custom-elements/master/custom-elements.min.js'));
}
if (!HTMLElement.prototype.attachShadow) {
polyfilled = true
loadPromises.push(loadScript('https://raw.githubusercontent.com/webcomponents/shadydom/master/shadydom.min.js'));
loadPromises.push(loadScript('https://raw.githubusercontent.com/webcomponents/shadycss/master/shadycss.min.js'));
}
Promise.all(loadPromises)
.then(e => console.log(`polyfilled ${polyfilled}`))
.then(e => {
class HelloWorld extends HTMLElement {
constructor() {
super()
this.template = document.createElement('template')
this.template.innerHTML = `
<style>
:host {
display: block;
box-sizing: border-box;
border: 1px solid red;
margin-top: 10px;
padding: 0px 5px;
}
</style>
<p>Test <slot></slot></p>
`
if (polyfilled) ShadyCSS.prepareTemplate(this.template, 'hello-world');
}
connectedCallback() {
const shadowRoot = this.attachShadow({ mode: 'open' })
shadowRoot.appendChild(this.template.content.cloneNode(true))
if (polyfilled) ShadyCSS.applyStyle(this);
}
}
customElements.define('hello-world', HelloWorld)
})
</script>
</body>
</html>
Shadow DOM polyfill won't create a real Shadow DOM but normal DOM elements,
The Custom Elements specification won't allow you to add elements in the normal DOM tree in constructor(),
Therefore, you should attach the fake Shadow DOM afterwards, that is inside the connectedCallback() method, instead of inside the constructor() method.
The ShadyCSS polyfill works fine with Edge and Firefox.

How to align fabric.Image objects horizontally?

I am simply trying to load three rectangular images and want them to align horizontally adjacent to each other. I thought setting the left property in fabric.Image.fromURL method would accomplish this but the tree images load stacked on top of each other. Also even though I include selectable:true, the images are not selectable. Am I using fabric.Image.fromURL incorrectly?
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<!-- Get version 1.1.0 of Fabric.js from CDN -->
<script src="js/fabric.js"></script>
<!-- Get the highest 1.X version of jQuery from CDN. Required for ready() function. -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(function () {
var canvas = new fabric.Canvas('canvas', {
backgroundColor: 'black',
selectionColor: 'blue',
selectionLineWidth: 0
// ...
});
debugger;
var tiles = [
"images/Green.png",
"images/Red.png",
"images/Yellow.png"
];
var offset = [
"0",
"200",
"400"
];
debugger;
for (i = 0; i < tiles.length; i++) {
fabric.Image.fromURL(tiles[i], function (img) {
img.scale(1.0).set({
left: offset[i],
top: 0,
selectable:true,
});
canvas.add(img).setActiveObject(img);
});
}
function handleDragStart(e) {
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
this.classList.add('img_dragging');
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}
e.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object.
// NOTE: comment above refers to the article (see top) -natchiketa
return false;
}
function handleDragEnter(e) {
// this / e.target is the current hover target.
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over'); // this / e.target is previous target element.
}
function handleDrop(e) {
// this / e.target is current target element.
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
var img = document.querySelector('#images img.img_dragging');
console.log('event: ', e);
var newImage = new fabric.Image(img, {
width: img.width,
height: img.height,
// Set the center of the new object based on the event coordinates relative
// to the canvas container.
left: e.layerX,
top: e.layerY
});
canvas.add(newImage);
return false;
}
function handleDragEnd(e) {
// this/e.target is the source node.
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
}
// Bind the event listeners for the image elements
var images = document.querySelectorAll('#images img');
[].forEach.call(images, function (img) {
img.addEventListener('dragstart', handleDragStart, false);
img.addEventListener('dragend', handleDragEnd, false);
});
// Bind the event listeners for the canvas
var canvasContainer = document.getElementById('canvas-container');
canvasContainer.addEventListener('dragenter', handleDragEnter, false);
canvasContainer.addEventListener('dragover', handleDragOver, false);
canvasContainer.addEventListener('dragleave', handleDragLeave, false);
canvasContainer.addEventListener('drop', handleDrop, false);
});
</script>
</head>
<body>
<div id="canvas-container">
<canvas id="canvas" width="600" height="200"></canvas>
</div>
<div id="images">
<img draggable="true" src="images/Red.png" width="50" height="50"></img>
<img draggable="true" src="images/Yellow.png" width="50" height="50"></img>
<img draggable="true" src="images/Green.png" width="50" height="50"></img>
</div>
</body>
</html>
There is a race condition between your fabric.Image.fromURL callback and the execution of the for loop, which prevents the images from showing.
If you print i and offset[i] inside your callback:
fabric.Image.fromURL(tiles[i], function (img) {
console.log(i, offset[i]);
...
});
you'll notice that i is 3 and offset[i] is undefined in all off the callbacks.
This happens because each of the callbacks retain a reference to the same instance of the i variable, and use its latest value at the time they execute. The for loop loops through its cycles, each time incrementing i, before any of your callbacks execute, leaving i with a final value of 3. When your callbacks execute, they try to set the left: value to offset[3], which is undefined, and fabric falls back to 0.
Solution
Variables in pre-ES6 javascript (unlike most languages) are only scoped to the function they are declared it, and code-blocks do not affect scope.
Place your image build logic into its own function, passing the current value of i as a parameter in each loop cycle. This will place the value into a new scope, and preserve the value.
Also, don't forget the var keyword in front of your i. Otherwise you're affecting the global namespace, which you want to avoid at all cost.
Here's what your code should look like:
for (var i = 0; i < tiles.length; i++) {
buildImage(i);
}
// creates a new scope for the passed in value of i when called:
function buildImage(i) {
fabric.Image.fromURL(tiles[i], function (img) {
img.scale(1.0).set({
left: offset[i],
top: 0,
selectable: true,
});
canvas.add(img).setActiveObject(img);
});
}
Finally, you may want to consider setting the originX and originY properties of the images, like so:
originX: 'left',
originY: 'top'
By default, fabric will use the center of the images as the point of origin when placing them, and your images will not be in full view of the canvas.
Update
Here is the fully working example. It is dependent on fabric, which needs to be placed in your js/ folder.

Create addListener click event for more than one shape on the Google map

Look at this code:
This creates four circles on the map in a same position and it creates addListener click event for each one too but I just can click on the last one. I want to fix it in a way that I can click on all of them to make setEditable(true) for each one.
<!DOCTYPE html>
<html>
<head>
<script
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDY0kkJiTPVd2U7aTOAwhc9ySH6oHxOIYM&sensor=false">
</script>
<script>
var selectedShape;
function clearSelection()
{
if(selectedShape)
{
selectedShape.setEditable(false);
selectedShape = null;
}
}
function setSelection(shape)
{
clearSelection();
selectedShape = shape;
shape.setEditable(true);
}
</script>
<script>
var amsterdam=new google.maps.LatLng(52.395715,4.888916);
function initialize()
{
var mapProp = {center:amsterdam, zoom:7, mapTypeId:google.maps.MapTypeId.ROADMAP};
var map = new google.maps.Map(document.getElementById("googleMap"),mapProp);
var myArray = [];
var myCity;
for(var i = 0; i < 4; i++)
{
myCity = new google.maps.Circle({
center:amsterdam,
radius:20000,
strokeColor:"#0000FF",
strokeOpacity:0.8,
strokeWeight:2,
fillColor:"#0000FF",
fillOpacity:0.4
});
myArray.push(myCity);
google.maps.event.addListener(myCity, 'click', function() {setSelection(myCity)});
myArray[i].setMap(map);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="googleMap" style="width:500px;height:380px;"></div>
</body>
</html>
Use this instead of myCity :
google.maps.event.addListener(myCity, 'click', function() {
setSelection(this)
});
Using setSelection(myCity) will refer to the last myCity created.

how to save and pass a double variable in asp.net c# mvc 3

Still having trouble with google maps in asp.net C# 4.0 mvc 3.
So now, I can view the google map in my webpage but when I put my coordinates, the google map doesn't appear anymore. I assume there must be something with the passing of my data and such? I am using sql server 2008. In my google map table, I have set longitude and latitude as integer because it doesn't have a double category. What should I do? Any advice/ suggestions? Thanks in advance :)
This is my code for my google map View
#{
ViewBag.Title = "GMAP";
Layout = "~/Views/Home/Gmap.cshtml";
}
<h2>GMAP</h2>
#section Scripts {
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
}
#section Styles {
html { height: 80% }
body { height: 80%; margin: 0px; padding: 0px }
#map_canvas { height: 80% }
}
<div id="map_canvas" style="width:80%; height:80%"></div>
<script type="text/javascript">
function initialize() {
var latlng = new google.maps.LatLng(#ViewData["Latitude"], #ViewData["Longitude"] );
var options = { zoom: 14, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
}
$(function () {
initialize();
});
</script>
Here is the code for my Google Map Controller
public ActionResult GMAP(int id){
var dataContext = new transDataContext();
Double Longitude = (Double)(from t in dataContext.TransactionModels
where t.id.Equals(id)
select t.longitude).Single();
Double latitude = (Double)(from t in dataContext.TransactionModels
where t.id.Equals(id)
select t.latitude).Single();
ViewData["Longitude"] = Longitude;
ViewData["Latitude"] = latitude;
return View();
}
In my google map table, I have set longitude and latitude as integer because it doesn't have a double category.
You have answered your own question. Lat and Long have to be doubles. -0.156 Long is going to end up as zero.

Google maps in firefox6 zooms znd scrolls page

I have problem with Firefox6 (don't know if it also concerns earlier versions).
I want to embed Google Map on page, and when page has scrollbars (is longer than viewport) mouse wheel not only zooms map but also scrolls page. I tried to catch mousewheel event and stop propagation but this event isn catchable when cursor os over map. When cursor is over map controls (zoom control, google logo, etc) i can catch event and stop propagation.
What is more strange it not happens always. Sometimes page srolls and after few scrolls it stops and mousewheel only zooms map (as expected). Sometimes page doesn't scroll and sometimes it scrolls with zoom all the time. Can't find pattern.
Source code is simple:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>test</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
window.onload = function(){
var latlng = new google.maps.LatLng(52.25, 21.01);
mapOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
zoomControl:true,
mapTypeControl:false
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
}
</script>
</head>
<body>
<p style="height:500px;">-lot of text-</p>
<div id="map_canvas" style="width:500px; height:500px;"></div>
<p style="height:500px;">-lot of text-</p>
</body>
</html>
Your problem is also described on code.google.com, this problem is only in Firefox, but it isn't a Firefox bug:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=3652
http://code.google.com/p/gmaps-api-issues/issues/detail?id=1605
Have also found out a workaround, that is not re-scrolling or re-zooming and works fine:
A new ScrollInterceptOverlay derived from google.maps.OverlayView, prepending a div on MapPanes.overlayMouseTarget:
Version with jQuery
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map($googlemap[0], mapOptions);
// Define a ScrollInterceptOverlay function
var ScrollInterceptOverlay = function (gmap) {
if (!(this instanceof ScrollInterceptOverlay)) return;
var $div;
var $mapDiv;
var initialize = function () {
$div = $('<div />').css({
position: 'absolute', top: 0, left: 0,
display: 'inline-block'
});
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
this.setMap(gmap);
};
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
this.onAdd = function () {
$div.prependTo(this.getPanes().overlayMouseTarget);
};
this.onRemove = function () {
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
$div.detach();
};
this.draw = function () {
if ($mapDiv && $mapDiv.length === 1) {
$div.css({
width: $mapDiv.outerWidth(),
height: $mapDiv.outerHeight()
});
}
};
var base_setMap = this.setMap;
this.setMap = function (map) {
$mapDiv = $(map.getDiv());
base_setMap.call(this, map);
};
initialize.call(this);
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay(gmap);
This workaround is using jQuery, required for calculating outerWidth and outerHeight, but also for better reading.
Version with pure javaScript
Tested live: http://fiddle.jshell.net/fhSMM/7/
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map(googlemap, mapOptions);
// Define a ScrollInterceptOverlay class function
var ScrollInterceptOverlay = function () {
if (!(this instanceof ScrollInterceptOverlay)) return;
var div;
// private instance function
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
// public instance function
this.onAdd = function () {
div = document.createElement('div');
div.style.display = 'inline-block';
div.style.position = 'absolute';
div.style.top = div.style.left = 0;
if (div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
var pane = this.getPanes().overlayMouseTarget;
var firstChild = pane.firstChild;
if (!firstChild) {
pane.appendChild(div);
}
else {
pane.insertBefore(div, firstChild);
}
};
// public instance function
this.onRemove = function () {
if (div) {
if (div.removeEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.removeEventListener("mousewheel", mouseScrollStop);
// Firefox
div.removeEventListener("DOMMouseScroll", mouseScrollStop);
div.removeEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.detachEvent) { // IE before version 9
div.detachEvent("onmousewheel", mouseScrollStop);
}
var parent = div.parentNode;
parent.removeChild(div);
}
// do not delete div var'iable
div = undefined;
};
// public instance function
this.draw = function () {
var map = this.getMap();
if (map) {
var mapDiv = map.getDiv();
if (mapDiv) {
var rect = mapDiv.getBoundingClientRect();
div.style.width = rect.width + 'px';
div.style.height = rect.height + 'px';
}
}
};
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay();
mapScrollInterceptor.setMap(gmap);
Please visit also http://metadea.de/V/ about what (real) javaScript class functions are, and why I like jQuery :)
Works now for me.
Also in Firefox, the map is zooming on mousescroll, but no more scrolling the document.
Edit: Updated support for MozMousePixelScroll, refined jS
For now it looks like firefox bug. Will close question when bug will be fixed.
I had the same issue.
You could try to start Firefox with a brand new profile (e.g. by starting the Profile Manager - executing 'firefox -P' on windows systems - and choosing 'Create...') and see if the problem persists.
I had several old but seemingly empty user profiles lying around in the VMs I used to verify if this was a bug in FF 6 and obviously installing only the new binaries didn't help. On the other hand, creating a blank profile did, so I can only think of this being a migration glitch. If major versions of FF are going to be released on a bi-monthly basis, though, a lot of people are going to suffer from similar issues.
Why not take UI control of zooming? This works well for me.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
</head>
<body>
<div class="canvas" style="width:600px;height:400px;"></div>
<script>
// Load event
$(function() {
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($('.canvas')[0], myOptions);
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
// Only a Mozilla bug
if($.browser.mozilla) {
// Wait for the map DOM to be ready
google.maps.event.addListenerOnce(map, 'idle', function() {
$('.canvas > div > div:first-child > div').bind('DOMMouseScroll', function(e) {
// setTimeout needed otherwise the return false has no effect
setTimeout(function() {
// Calculate new center
var offset = $('.canvas').offset();
var pos = overlay.getProjection().fromContainerPixelToLatLng(new google.maps.Point(e.pageX-offset.left, e.pageY-offset.top));
// Calculate new zoom level
var zoom = map.getZoom();
if(e.detail < 0) zoom++;
else if(e.detail > 0) zoom--;
map.setCenter(pos);
map.setZoom(zoom);
}, 1);
// Stop propagation (prevent default)
return false;
});
});
}
});
</script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>

Resources