简体   繁体   English

Chrome 和 Firefox 中不一致的 SVG 文本对齐方式

[英]Inconsistent SVG text alignment in Chrome and Firefox

I'm drawing SVG marker icons on a Leaflet.js map.我正在 Leaflet.js 地图上绘制 SVG 标记图标。 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.我已经能够让它在 Chrome 中按需要工作,但文本位置在 Firefox 中关闭。

截屏

Left is Chrome (55.0.2883.95), right is Firefox (50.0.1).左边是 Chrome (55.0.2883.95),右边是 Firefox (50.0.1)。

This is the custom Leaflet.Icon class I'm using:这是我正在使用的自定义Leaflet.Icon类:

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.我通过设置text-anchor="middle"alignment-baseline="central"加上xy坐标来定位文本。

This is the HTML created in the DOM when the marker is added:这是添加标记时在 DOM 中创建的 HTML:

<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 没有正确定位文本?

Firefox does not currently support alignment-baseline . Firefox 目前不支持alignment-baseline It does support dominant-baseline , which amounts to pretty much the same thing for your use case.它确实支持dominant-baseline ,这对于您的用例来说几乎是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM