当位置比例发生变化时,保持SVG元素的固定大小

7

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

<?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像素,而是根据视口大小进行缩放,因此它会很小。
例如,在地图上会出现这个问题。当用户在地图上缩放时,代表城市位置的点和标签的大小应该保持不变,而不是随着用户的缩放而变大或变小。

1
找出你所缩放的比例,并对你想要看到未经缩放的元素应用反向变换。 - Robert Longson
3个回答

6

使用 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可以生成的形状。也许它的开销更小,如果不是,至少它很容易使用。 我正在使用svg-pan-zoom库,在Ubuntu 14.04上使用Chromium版本45.0.2454.101
<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"/>

1
您可以采用非常接近的方法:您可以使用一个嵌套的SVG元素,其高度和宽度以SVG视口对角线的百分比表示。如果您知道屏幕上SVG的大小,则可以用百分比近似100px。
您还需要使用视口作为地图平移和缩放的手段。 这适用于包括文本在内的任何元素;使用%单位的字体大小不是指SVG视口,因此要获得恒定的字体大小,您需要将其封装在另一个具有%单位大小的SVG元素中。
注意:SVG虽然大小固定,但相对于内部SVG的左上角,它将呈现为按比例缩放。
另请参见:与另一个答案中类似问题的相同方法。

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>

`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接