I'm drawing SVG marker icons on a Leaflet.js map. The icons represent weather stations and they are rotated according to the wind direction and show the average wind speed as an overlay.
I have been able to get this to work as desired in Chrome but the text position is off in Firefox.
Left is Chrome (55.0.2883.95), right is Firefox (50.0.1).
This is the custom Leaflet.Icon
class I'm using:
window.RemoteWind = window.RemoteWind || {};
// This uses Chroma.js to build a color scale which is used for wind speed.
// http://gka.github.io/chroma.js
RemoteWind.color_scale = chroma.scale([
'lightblue',
'green',
'red',
'purple'
])
.mode('hsl') // the blending mode
.domain([0, 7, 15, 25]); // the distinct steps for each.
RemoteWind.VectorIcon = L.Icon.extend({
options: {
height: 26,
width: 26,
stroke: 'white',
strokeWidth: 2,
circle: {
cx: 13,
cy: 13,
r: 13
}
},
_createSVG: function(){
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttributeNS(null, 'version', '1.1')
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
svg.setAttribute('height', this.options.height);
svg.setAttribute('width', this.options.width);
return svg;
}
});
/*
* Vector based icon for a station
*/
RemoteWind.StationIcon = RemoteWind.VectorIcon.extend({
options: {
className: 'leaflet-station-icon active',
speed: 0,
direction: 0,
path: {
d: "M26,19c0-2.2-0.6-4.4-1.6-6.2C22.2,8.8,13,0,13,0S3.8,8.7,1.6,12.8c-1,1.8-1.6,4-1.6,6.2c0,7.2,5.8,13,13,13 S26,26.2,26,19z"
}
},
createIcon: function (oldIcon) {
var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'),
svg = this._createSVG(),
g = document.createElementNS('http://www.w3.org/2000/svg', 'g'),
txt_g = document.createElementNS('http://www.w3.org/2000/svg', 'g'),
options = this.options,
path,
txt;
g.setAttributeNS(null, "transform", "translate(0,-6)");
path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttributeNS(null, 'd', "M26,19c0-2.2-0.6-4.4-1.6-6.2C22.2,8.8,13,0,13,0S3.8,8.7,1.6,12.8c-1,1.8-1.6,4-1.6,6.2c0,7.2,5.8,13,13,13 S26,26.2,26,19z");
path.setAttributeNS(null, 'stroke', this.options.stroke);
path.setAttributeNS(null, 'stroke-width', this.options.strokeWidth);
path.setAttributeNS(null, 'fill', RemoteWind.color_scale(options.speed).name() );
path.setAttributeNS(null, 'transform', 'rotate(% 13 19)'.replace('%', options.direction));
txt = document.createElementNS('http://www.w3.org/2000/svg', 'text');
txt.innerHTML = Math.round(options.speed).toString();
txt.setAttributeNS(null, 'fill', 'white');
txt.setAttributeNS(null, 'x', this.options.height / 2);
txt.setAttributeNS(null, 'y', this.options.width / 2);
txt.setAttributeNS(null, 'text-anchor', 'middle');
txt.setAttributeNS(null, 'alignment-baseline', 'central');
g.appendChild(path);
txt_g.appendChild(txt);
svg.appendChild(g);
svg.appendChild(txt_g);
div.appendChild(svg);
this._setIconStyles(div, 'icon');
return div;
},
createShadow: function () {
return null;
}
});
RemoteWind.stationIcon = function (options) {
return new RemoteWind.StationIcon(options);
};
I'm positioning the text by setting text-anchor="middle"
and alignment-baseline="central"
plus the x
and y
coordinates.
This is the HTML created in the DOM when the marker is added:
<div class="leaflet-marker-icon leaflet-station-icon active leaflet-zoom-animated leaflet-interactive" title="Åre strand | 2(3) m/s" tabindex="0" style="transform: translate3d(-367px, 85px, 0px); z-index: 85; outline: none;">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="26" width="26">
<g transform="translate(0,-6)">
<path d="M26,19c0-2.2-0.6-4.4-1.6-6.2C22.2,8.8,13,0,13,0S3.8,8.7,1.6,12.8c-1,1.8-1.6,4-1.6,6.2c0,7.2,5.8,13,13,13 S26,26.2,26,19z" stroke="white" stroke-width="2" fill="#64e0d2" transform="rotate(338 13 19)"></path>
</g>
<g>
<text fill="white" x="13" y="13" text-anchor="middle" alignment-baseline="central">2</text>
</g>
</svg>
</div>
Why is firefox not positioning the text correctly?
Firefox does not currently support alignment-baseline
. It does support dominant-baseline
, which amounts to pretty much the same thing for your use case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With