我们终于找到了解决方案,以防万一有人遇到同样的问题:
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;
}