Accepted answer

Your original calculations make use of the width/height of the marker being 20x20 pixels:

return latLng[0] - 10;

Your "recalcs" need to do this to as well with the resized image. I would stash the "real" x/y positoin in your data, so you can re-perform the calculations:

datum.realx = latLng[0];
if ( latLng ) return latLng[0] - 10;

And then move them in your zoom handler:

  .attr("height", 20*(1/scale))
  .attr("width", 20*(1/scale))
  .attr("x", function(d){
    return d.realx  - (20*(1/scale)/2);
  .attr("y", function(d){
    return d.realy  - (20*(1/scale));

Related Query

More Query from same tag