【问题标题】:Keeping SVG elements to a fixed size while position scales在位置缩放时将 SVG 元素保持为固定大小
【发布时间】:2021-11-11 08:46:48
【问题描述】:

如何在背景和位置坐标发生变化时将文本或对象保持为固定大小?例如:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:ev="http://www.w3.org/2001/xml-events" 
    width="100%" height="100%"
    viewBox="0 0 50000 50000"
    >
    <circle  cx="25000"  cy="25000" r="100px" fill="red" />
</svg>

在这段代码中,圆不会是 100 像素,它会根据 viewbox 的大小进行缩放,所以会很小。

例如,这个问题体现在地图中。当您放大和缩小地图时,您希望代表城市位置的点和标签保持相同大小,而不是在用户放大时变大或变小。

【问题讨论】:

  • 算出你放大了多少,并在你想看到未缩放的元素上应用逆变换。

标签: dictionary svg graphics transformation


【解决方案1】:

将 viewBox 比例的倒数应用于半径,例如

var circle = document.getElementById('c');
var root = document.getElementById('root');
var matrix = circle.getCTM();
circle.r.baseVal.value /= matrix.a;
<svg id="root" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:ev="http://www.w3.org/2001/xml-events" 
    width="100%" height="100%"
    viewBox="0 0 50000 50000"
    >
    <circle  id="c" cx="25000"  cy="25000" r="100px" fill="red" />
</svg>

如果我将 viewBox 值加倍,则圆圈的大小保持不变。

var circle = document.getElementById('c');
var root = document.getElementById('root');
var matrix = circle.getCTM();
circle.r.baseVal.value /= matrix.a;
<svg id="root" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:ev="http://www.w3.org/2001/xml-events" 
    width="100%" height="100%"
    viewBox="0 0 100000 100000"
    >
    <circle  id="c" cx="25000"  cy="25000" r="100px" fill="red" />
</svg>

您可能希望使用椭圆,以便可以通过矩阵 a 和 d 值分别缩放 x 和 y。

【讨论】:

    【解决方案2】:

    vector-effect="non-scaling-stroke" 属性禁用线的缩放。在同一位置画一条以圆端为起点和终点的线将产生一个圆。

    这仅适用于stroke-linecap 可以生成的形状。也许它的开销更少,如果没有,至少它很容易。 我在 Ubuntu 14.04 上使用带有 Chromium 版本 45.0.2454.101svg-pan-zoom 库。

    <line x1="250" x2="250" y1="250" y2="250" stroke-width="5" 
    stroke="rgb(0,0,0)" stroke-linecap="round" vector-effect="non-scaling-stroke"/>
    

    【讨论】:

      【解决方案3】:

      您可以做一些非常接近的事情:您可以使用嵌套的 svg 元素,其高度和宽度占 svg viewBox 对角线的百分比。如果您知道屏幕上 svg 的大小,您可以近似为 100px 的百分比。

      您还需要使用 viewBox 作为平移和缩放地图的手段。 这适用于包含的任何元素文本;对字体大小使用 % 单位并不是指 svg viewBox,因此获得恒定字体大小的唯一方法是,您需要封装在另一个 svg 元素中,其大小为 % 单位。

      警告:svg 的大小虽然固定,但会相对于内部 svg 的左上角按比例显示。

      The same approach to a similar problem in another answer.

      for(let i = 0; i < 12; i++) {
        let a = (i - 4)*5
        setTimeout(function() {
          document.querySelector('#svg').setAttribute('viewBox',
            `${a} ${a} ${100 - 2*a} ${100 - 2*a}`);
        }, 500 * i);
       }
        
      <svg id="svg" width="100px" height="100px" xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
          <svg x='35' y='35' width='10%' height='10%' viewBox='0 0 100 100'>
             <circle  cx='50'  cy='50' r='50' fill='red'/>
          </svg>
           <circle  cx='65'  cy='65' r='5%' fill='red'/>
           <circle  cx='35'  cy='65' r='10' fill='red'/>
      </svg>

      `

      【讨论】:

        猜你喜欢
        • 2013-06-01
        • 2015-04-14
        • 1970-01-01
        • 2012-08-24
        • 2012-08-04
        • 2014-07-19
        • 2020-10-10
        • 2011-11-26
        • 1970-01-01
        相关资源
        最近更新 更多