奇怪的对角线 viewBox SVG 行为
Strange diagonal viewBox SVG Behaviour
试图弄清楚这个 svg viewBox 是如何工作的,但遗憾的是下面的代码打破了我们所知道的所有逻辑,哈哈。请有人解释这是错误还是正确的 svg 行为。我看不出我哪里错了...
<svg class="symbol"><symbol id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"></path></symbol></svg>
这是我的 svg 符号,我正在尝试堆叠更多符号(水平和垂直)
//vertical stack ->viewBox = 0, 0, 10*1, 7*2
<svg viewBox="0 0 10 14">
<use href="#Atom"/>
<use href="#Atom" y="7"/>
</svg>
//horizontal stack ->viewBox = 0, 0, 10*2, 7*1
<svg viewBox="0 0 20 7">
<use href="#Atom"/>
<use href="#Atom" x="10"/>
</svg>
//"diagonal" stack ->viewBox = 0, 0, 10*2, 7*2
<svg viewBox="0 0 20 14">
<use href="#Atom"/>
<use href="#Atom" x="10"/>
<use href="#Atom" y="7"/>
</svg>
第一个是垂直的 2 个符号,所以我保留了与符号相同的 viewBox,但将高度从 7 加倍到 14。效果很好。
第二个是水平的 2 个符号,所以我保留了与符号相同的 viewBox,但将宽度从 10 加倍到 20。效果也很好。
第三个是水平2个符号,垂直2个符号,使viewBox的宽度和高度都是原来的两倍。这是行不通的。
正如您从图像中看到的那样,符号变得更加混乱(似乎我的 viewBox 有误)
This 有点像我正在寻找的东西(尽管如您所见,我正在使用溢出:可见并且符号超出了视图框)
有人可以解释一下我在这里犯了什么错误吗?非常感谢任何帮助。
这里有一个 codepen 用来玩这个东西
你的符号想要全宽或全高
当你只拉伸视口的一个维度时,它会很好地适应,因为它占据了整个宽度或高度,并且停止向另一个方向拉伸,因为它想保持纵横比。
但在这个 svg
视口中比符号大 2 倍,所以它可以全部使用
这是简单的解决方案
.svg {
max-width: 200px;
border: 1px solid red;
}
<svg class="svg" viewBox="0 0 20 14">
<use href="#Atom" x="0" y="0" width="50%" />
<use href="#Atom" x="0" y="7" width="50%" />
<use href="#Atom" x="10" y="0" width="50%" />
<use href="#Atom" x="10" y="7" width="50%" />
</svg>
<svg class="symbol"><symbol id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"></path></symbol></svg>
更新:
如果您不想手动将 width
添加到 use
标签并且您正在以编程方式创建它们(我假设您使用 javascript 但您可以使用相同的逻辑对于其他语言)你只想计算视口中的行和列并计算每个 use
的宽度和高度
这里有一个例子
const config = {
svg: {
width: 20,
height: 14,
rows: 2,
cols: 2,
symbol: '#Atom'
}
}
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 '+config.svg.width+' '+config.svg.height);
for (let i = 0; i < config.svg.rows; i++) {
for (let j = 0; j < config.svg.cols; j++) {
const xPosition = (config.svg.width / config.svg.rows) * i;
const yPosition = (config.svg.height / config.svg.cols) * j;
const width = (100 / config.svg.rows);
const height = (100 / config.svg.cols);
const svgUse = document.createElementNS('http://www.w3.org/2000/svg', 'use');
svgUse.setAttribute('href', config.svg.symbol);
svgUse.setAttribute('x', xPosition);
svgUse.setAttribute('y', yPosition);
svgUse.setAttribute('width', width + '%');
svgUse.setAttribute('height', height + '%');
svg.append(svgUse);
}
}
document.body.prepend(svg)
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<svg class="symbol"><symbol id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"></path></symbol></svg>
</body>
</html>
所以我最后回复了自己,但我真的要感谢@ciekals11 的输入。
获得我想要的结果的解决方案是在我的符号中指定宽度和高度属性。这使一切都完美无缺。不知道为什么它确实需要这个,但无论如何我会再次分享我的符号,这样你就可以看到区别了。
<svg class="symbol"><symbol width="10" height="7" id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"/></symbol></svg>
试图弄清楚这个 svg viewBox 是如何工作的,但遗憾的是下面的代码打破了我们所知道的所有逻辑,哈哈。请有人解释这是错误还是正确的 svg 行为。我看不出我哪里错了...
<svg class="symbol"><symbol id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"></path></symbol></svg>
这是我的 svg 符号,我正在尝试堆叠更多符号(水平和垂直)
//vertical stack ->viewBox = 0, 0, 10*1, 7*2
<svg viewBox="0 0 10 14">
<use href="#Atom"/>
<use href="#Atom" y="7"/>
</svg>
//horizontal stack ->viewBox = 0, 0, 10*2, 7*1
<svg viewBox="0 0 20 7">
<use href="#Atom"/>
<use href="#Atom" x="10"/>
</svg>
//"diagonal" stack ->viewBox = 0, 0, 10*2, 7*2
<svg viewBox="0 0 20 14">
<use href="#Atom"/>
<use href="#Atom" x="10"/>
<use href="#Atom" y="7"/>
</svg>
第一个是垂直的 2 个符号,所以我保留了与符号相同的 viewBox,但将高度从 7 加倍到 14。效果很好。
第二个是水平的 2 个符号,所以我保留了与符号相同的 viewBox,但将宽度从 10 加倍到 20。效果也很好。
第三个是水平2个符号,垂直2个符号,使viewBox的宽度和高度都是原来的两倍。这是行不通的。
正如您从图像中看到的那样,符号变得更加混乱(似乎我的 viewBox 有误)
This 有点像我正在寻找的东西(尽管如您所见,我正在使用溢出:可见并且符号超出了视图框)
有人可以解释一下我在这里犯了什么错误吗?非常感谢任何帮助。
这里有一个 codepen 用来玩这个东西
你的符号想要全宽或全高 当你只拉伸视口的一个维度时,它会很好地适应,因为它占据了整个宽度或高度,并且停止向另一个方向拉伸,因为它想保持纵横比。
但在这个 svg
视口中比符号大 2 倍,所以它可以全部使用
这是简单的解决方案
.svg {
max-width: 200px;
border: 1px solid red;
}
<svg class="svg" viewBox="0 0 20 14">
<use href="#Atom" x="0" y="0" width="50%" />
<use href="#Atom" x="0" y="7" width="50%" />
<use href="#Atom" x="10" y="0" width="50%" />
<use href="#Atom" x="10" y="7" width="50%" />
</svg>
<svg class="symbol"><symbol id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"></path></symbol></svg>
更新:
如果您不想手动将 width
添加到 use
标签并且您正在以编程方式创建它们(我假设您使用 javascript 但您可以使用相同的逻辑对于其他语言)你只想计算视口中的行和列并计算每个 use
这里有一个例子
const config = {
svg: {
width: 20,
height: 14,
rows: 2,
cols: 2,
symbol: '#Atom'
}
}
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 '+config.svg.width+' '+config.svg.height);
for (let i = 0; i < config.svg.rows; i++) {
for (let j = 0; j < config.svg.cols; j++) {
const xPosition = (config.svg.width / config.svg.rows) * i;
const yPosition = (config.svg.height / config.svg.cols) * j;
const width = (100 / config.svg.rows);
const height = (100 / config.svg.cols);
const svgUse = document.createElementNS('http://www.w3.org/2000/svg', 'use');
svgUse.setAttribute('href', config.svg.symbol);
svgUse.setAttribute('x', xPosition);
svgUse.setAttribute('y', yPosition);
svgUse.setAttribute('width', width + '%');
svgUse.setAttribute('height', height + '%');
svg.append(svgUse);
}
}
document.body.prepend(svg)
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<svg class="symbol"><symbol id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"></path></symbol></svg>
</body>
</html>
所以我最后回复了自己,但我真的要感谢@ciekals11 的输入。
获得我想要的结果的解决方案是在我的符号中指定宽度和高度属性。这使一切都完美无缺。不知道为什么它确实需要这个,但无论如何我会再次分享我的符号,这样你就可以看到区别了。
<svg class="symbol"><symbol width="10" height="7" id="Atom" preserveAspectRatio="xMinYMin meet" viewBox="0 0 10 7"><path d="M3 6 4 7 6 7 4 4 5 3 8 7 10 7 5 0 0 7 2 7Z"/></symbol></svg>