13

我目前正在使用 SVG,但走到了死胡同。

SVG 有线条,应该与缩放一起缩放(以便它们保持平衡:例如 100% 宽度 10px --> 10% 宽度 1px)

stroke-widths我用这段代码缩放所有:

var svgPath = this._svgContainer.find('svg [class*="style"]');
for (var i = 0; i < svgPath.length; ++i) {
  var newStrokeWidth = this._oldStrokeWidth[i] * (1 / (width / imgData.w));

  $(svgPath[i]).css(
    'stroke-width', newStrokeWidth
  );
}

width缩放后的新宽度在哪里,imgData.w是原始未缩放的宽度。

问题是,如果我放大到远处。笔画变小并导致子像素渲染。据说黑线会变成灰色。

我的想法是在某个点剪辑值以防止它。但据我所知,我也必须考虑设备像素比率,因为不同的屏幕(桌面、移动、4K)

如果有人可以帮助我解决我的问题,那就太好了

4

2 回答 2

1

我们终于找到了解决方案,以防万一有人遇到同样的问题:

1)由于在代码的完全不同部分中平移this._$svgElement和计算元素是“介于”像素之间。vpx例如 x 为 100.88945px)。这会导致线条模糊。我用一个简单的Math.round()修复了这部分。

this._hammerCanvas.on('panmove', (event: any) => {
        const translate3d = 'translate3d(' + Math.round(this._oldDeltaX + ((vpx === imgData.x) ? 0 : vpx) + event.deltaX) + 'px, ' + Math.round(this._oldDeltaY + ((vpy === imgData.y) ? 0 : vpy) + event.deltaY) + 'px, 0)';
        this._$svgElement.css({
          transform: translate3d
        });
}

2) 为了解决 SVG 视口和线条强度之间的问题,我必须实现一种方法来计算关于 svgs 尺寸的笔画宽度等于 1 个“真实”像素。

更新后的代码如下所示:(这是初始代码,在从服务器加载 SVG 后。在缩放内部,上面的旧代码仍然相同)

    const pixelRatio = devicePixelRatio || 1;
    const widthRatio = this._initSVGWidth / svgContainerWidth;
    const heightRatio = this._initSVGHeight / svgContainerHeight;
    this._svgZoomFactor = Math.max(widthRatio, heightRatio);
    const strokeWidth1px = this.computeStrokeWidth1px(widthRatio, heightRatio);

    for (let i = 0; i < svgPaths.length; ++i) {
      this._initalStrokeWidth[i] = parseFloat($(svgPaths[i]).css('stroke-width'));

      const newStrokeWidth = Math.max(strokeWidth1px / pixelRatio, this._svgZoomFactor * this._initalStrokeWidth[i]);

      $(svgPaths[i])[0].setAttribute('style', 'stroke-width:' + newStrokeWidth);
      this._oldStrokeWidth[i] = newStrokeWidth;
    }

和计算:

  protected computeStrokeWidth1px (widthRatio: number, heightRatio: number): number {
    const viewBox = this._$svgElement[0].getAttribute('viewBox').split(' ');
    const viewBoxWidthRatio = parseFloat(viewBox[2]) / this._$svgElement.width();
    const viewBoxHeightRatio = parseFloat(viewBox[3]) / this._$svgElement.height();
    return widthRatio > heightRatio ? viewBoxWidthRatio : viewBoxHeightRatio;
  }
于 2019-08-06T13:59:44.830 回答
0
var newStrokeWidth = this._oldStrokeWidth[i] * (1 / (width / imgData.w));
newStrokeWidth = (newStrokeWidth < 1) ? 1 : newStrokeWidth;

newStrokeWidth 将始终为 1 或更大

于 2019-07-31T13:01:11.840 回答