【问题标题】:How can I scale an SVG coordinate system without scaling fonts?如何在不缩放字体的情况下缩放 SVG 坐标系?
【发布时间】:2019-03-12 21:15:43
【问题描述】:

我正在制作这样的数据可视化:

使用viewBox来缩放SVG会很方便,这样图形的宽度就可以缩放到数据范围的宽度。

本例中的数据点是 12,549,因此我希望范围从 0 到 14,000,并使用宽度为 12,549 的 rect 将其呈现在宽度为 14,000 的 viewBox 中。换句话说,为我的数据使用自然单位。

但是当我这样做时,我的轴上的字体缩放,10px的字体也缩放,变得非常小以至于看不到。

所以我需要一种在不缩放字体单位的情况下缩放绘图单位的方法,但我看不到这样做的方法。

更新

这里是有问题的代码:

<svg width="960" height="50" class="bullet2" style="margin-top: 10px;">
  <svg viewBox="0 0 14000 25" preserveAspectRatio="none" width="100%" height="25" class="bars">
<rect x="0" y="0" width="14000" height="25" class="background"/>
<rect x="0" y="0" height="12.5" width="12549" class="item player"/>
<rect x="0" y="12.5" height="12.5" width="3750" class="item team-average"/>
<line x1="2000" x2="2000" y1="0" y2="25" class="marker" style="stroke-width: 29.1667px;"/>
  </svg>
  <g class="axis">
<g transform="translate(0, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">0</text>
</g>
<g transform="translate(140, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">2000</text>
</g>
<g transform="translate(280, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">4000</text>
</g>
<g transform="translate(420, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">6000</text>
</g>
<g transform="translate(560, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">8000</text>
</g>
<g transform="translate(700, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">10000</text>
</g>
<g transform="translate(840, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">12000</text>
</g>
<g transform="translate(980, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">14000</text>
</g>
  </g>
</svg>

请注意内部svg 元素上的viewBox,按所述对其进行缩放。我尝试在外部svg 元素上使用相同的缩放比例,该元素还包括轴,但是当我这样做时,图像看起来像这样:

轴标签在那里,但它们缩放了,14000像素缩放中的10px字体太小了,你看不到。

【问题讨论】:

标签: html svg


【解决方案1】:

这是我对您问题的解决方案。我推荐阅读SVGPointcreateSVGPoint。我认为本书中的信息特别有用:Using SVG with CSS3 and HTML5: Vector Graphics for Web Design

function init(){
  // a function called on resize
  // the function get the new font-size and set the new value of the "font-size"
  let fontSize = 25;
  let newSize = getValue(fontSize);
  // reset the font size
  theText.setAttributeNS(null,"font-size",newSize.x)
}


setTimeout(function() {
		init();
		addEventListener('resize', init, false);
}, 15);


// a function used to recalculate the font size on resize
function getValue(size){
var p = svg.createSVGPoint();
p.x = size;
p.y = 0;
p = p.matrixTransform(svg.getScreenCTM().inverse());
return p
}
svg{border:1px solid;}
<svg id="svg" viewBox="0 0 1000 100">
  <line x1="50" x2="950" y1="50" y2="50" stroke-width="20" stroke="skyblue" />
  
  <line x1="500" x2="500" y1="30" y2="70" stroke-width="1" stroke="#999" />
  <text id="theText"  dominant-baseline="middle" text-anchor="middle" x="500" y="85" font-size="16" >middle</text>
</svg>

更新

您能解释一下这个解决方案的工作原理吗?

代码中有cmets。我还添加了来自Using SVG with CSS3 and HTML5: Vector Graphics for Web Design 的引用:

每个可以进行变换的 SVG 元素 [....] 都有一个 getScreenCTM() 方法。 CMT 代表累积变换矩阵。屏幕 CMT [....] 定义了如何将元素坐标系中的点转换回文档窗口的原始、未缩放、未转换的坐标系。它包括对此元素及其祖先元素的转换以及 viewBox 缩放。

我希望这是有用的。但是我认为你需要阅读本书中的整个第 18 章才能完全理解代码。

【讨论】:

  • 您能解释一下这个解决方案是如何工作的吗? (没有解释的代码块没有那么有用)
  • 我已经用我认为相关的书中引用更新了答案
  • 谢谢。我不是 OP;-)
【解决方案2】:

请给Minimal, Complete, and Verifiable example

有两种方法可以解决您的模糊/一般缩放问题:

  • 1) 将缩放 SVG 放入容器 SVG?堆叠;并且永远不要缩放容纳字体的容器,相对于 child SVG 的百分比。

  • 2) states here 可以使用绝对 px 或相对 em 单位缩放字体。请参阅here for valid length

    我不知道是否可以设置rem 单位,但如果可以,试试是否可行?

(我经常在场合和 CSS 上使用 SVG,所以我的建议中可能存在差距)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-28
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多