在位置缩放时将 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.101
的 svg-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>
`
如何在背景和位置坐标发生变化时将文本或对象保持在固定大小?例如:
<?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
.
45.0.2454.101
的 svg-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>
`