在位置缩放时将 SVG 元素保持为固定大小

Keeping SVG elements to a fixed size while position scales

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

<?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 比例的倒数应用于半径,例如

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。

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"/>

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

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

警告:虽然 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>

`