SVG 元素的 3d 变换
3d transforms on SVG element
是否可以在 SVG 元素上使用 3d 变换实现透视?
我说的是类似于 Star Wars 开场标题在 3d 视角下的样子。这是一个 jsfiddle,使用 CSS3 3d 变换实现了预期的效果:
<section style="transform: perspective(200px) rotateX(-30deg); transform-origin: 50% 100%; text-align: justify; width: 100px;">
<p style="backface-visibility: hidden;">TEXTTEXTTEXT</p>
</section>
2018 年 11 月更新:
测试最新 chrome 问题中的代码片段,Firefox 有效。虽然对 svg 元素的 3d 转换的支持不是很广泛,但浏览器正在越来越多地实现它。
原始答案:
SVG 元素不支持 3D 变换。不过有一些解决方法:
如果 svg 不包含不应转换的元素,您可以对 SVG 元素本身使用 CSS 3d 转换 :
svg {
width: 70%;
margin: 0 auto;
display: block;
-webkit-transform: perspective(300px) rotateX(30deg);
transform: perspective(300px) rotateX(30deg);
}
<svg viewbox="0 0 100 20">
<text x="0" y="20">TEXTEXTEX</text>
</svg>
对于多边形,您可以使 2D 多边形看起来像 3D 多边形。在下面的示例中,红色矩形是 3D 旋转的 (rotateX(40deg)
),黑色矩形是 2D SVG 多边形,看起来像 3D 旋转的矩形:
div{
display:inline-block;
width:200px; height:100px;
background:red;
transform:perspective(500px) rotateX(40deg);
}
svg{
display:inline-block;
width:220px; height:auto;
}
div, svg{
display:inline-block;
margin:0 10px;
}
<div></div>
<svg viewbox="0 0.5 10 4">
<polygon points="9.9 4.1 0.1 4.1 0.7 0.6 9.3 0.6" fill=""/>
</svg>
<svg>
元素内支持 3D 变换(f.e。在 <circle>
上)(至少在某种程度上,透视似乎只是等轴测)。
例如,这里是 transform: rotate3d
应用于 <circle>
元素的动画(仅在 Chrome 中测试):
body, html {
background: black;
width: 100%; height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
}
svg {
width: 100%;
}
.gAExgp {
transform-origin: 50% 50% 0px;
animation-name: phEs, ipaUyp;
animation-duration: 4s, 7s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.PwswZ {
transform-origin: 50% 50% 0px;
animation-name: gcRPJT, ipaUyp;
animation-duration: 4s, 8s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes phEs {
50% {
transform: rotate3d(0, 2, 1, 180deg);
}
100% {
transform: rotate3d(0, 2, 1, 360deg);
}
}
@keyframes gcRPJT {
50% {
transform: rotate3d(2, 0, 1, 180deg);
}
100% {
transform: rotate3d(2, 0, 1, 360deg);
}
}
@keyframes ipaUyp {
0% {
stroke: magenta;
}
33% {
stroke: cyan;
}
66% {
stroke: yellow;
}
100% {
stroke: magenta;
}
}
<!-- Logo from https://rebassjs.org -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" style="display:block;max-width:100%;margin:0;fill:none;stroke:cyan" vector-effect="non-scaling-stroke" class="sc-htoDjs hCHUAb"><circle cx="32" cy="32" r="32" fill="#000" stroke="none"></circle><circle cx="32" cy="32" r="30" stroke-width="1" vector-effect="non-scaling-stroke" opacity="0.5"></circle><g><circle cx="32" cy="32" r="24" stroke-width="2" vector-effect="non-scaling-stroke" class="sc-dnqmqq gAExgp"></circle><circle cx="32" cy="32" r="24" stroke-width="2" vector-effect="non-scaling-stroke" class="sc-iwsKbI PwswZ"></circle></g><text x="32" y="34" text-anchor="middle" font-family="system-ui, sans-serif" font-weight="bold" font-size="4" stroke="none" fill="white" style="text-transform:uppercase;letter-spacing:0.5em">Rebass</text></svg>
是否可以在 SVG 元素上使用 3d 变换实现透视?
我说的是类似于 Star Wars 开场标题在 3d 视角下的样子。这是一个 jsfiddle,使用 CSS3 3d 变换实现了预期的效果:
<section style="transform: perspective(200px) rotateX(-30deg); transform-origin: 50% 100%; text-align: justify; width: 100px;">
<p style="backface-visibility: hidden;">TEXTTEXTTEXT</p>
</section>
2018 年 11 月更新:
测试最新 chrome 问题中的代码片段,Firefox 有效。虽然对 svg 元素的 3d 转换的支持不是很广泛,但浏览器正在越来越多地实现它。
原始答案:
SVG 元素不支持 3D 变换。不过有一些解决方法:
如果 svg 不包含不应转换的元素,您可以对 SVG 元素本身使用 CSS 3d 转换 :
svg {
width: 70%;
margin: 0 auto;
display: block;
-webkit-transform: perspective(300px) rotateX(30deg);
transform: perspective(300px) rotateX(30deg);
}
<svg viewbox="0 0 100 20">
<text x="0" y="20">TEXTEXTEX</text>
</svg>
对于多边形,您可以使 2D 多边形看起来像 3D 多边形。在下面的示例中,红色矩形是 3D 旋转的 (rotateX(40deg)
),黑色矩形是 2D SVG 多边形,看起来像 3D 旋转的矩形:
div{
display:inline-block;
width:200px; height:100px;
background:red;
transform:perspective(500px) rotateX(40deg);
}
svg{
display:inline-block;
width:220px; height:auto;
}
div, svg{
display:inline-block;
margin:0 10px;
}
<div></div>
<svg viewbox="0 0.5 10 4">
<polygon points="9.9 4.1 0.1 4.1 0.7 0.6 9.3 0.6" fill=""/>
</svg>
<svg>
元素内支持 3D 变换(f.e。在 <circle>
上)(至少在某种程度上,透视似乎只是等轴测)。
例如,这里是 transform: rotate3d
应用于 <circle>
元素的动画(仅在 Chrome 中测试):
body, html {
background: black;
width: 100%; height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
}
svg {
width: 100%;
}
.gAExgp {
transform-origin: 50% 50% 0px;
animation-name: phEs, ipaUyp;
animation-duration: 4s, 7s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.PwswZ {
transform-origin: 50% 50% 0px;
animation-name: gcRPJT, ipaUyp;
animation-duration: 4s, 8s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes phEs {
50% {
transform: rotate3d(0, 2, 1, 180deg);
}
100% {
transform: rotate3d(0, 2, 1, 360deg);
}
}
@keyframes gcRPJT {
50% {
transform: rotate3d(2, 0, 1, 180deg);
}
100% {
transform: rotate3d(2, 0, 1, 360deg);
}
}
@keyframes ipaUyp {
0% {
stroke: magenta;
}
33% {
stroke: cyan;
}
66% {
stroke: yellow;
}
100% {
stroke: magenta;
}
}
<!-- Logo from https://rebassjs.org -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" style="display:block;max-width:100%;margin:0;fill:none;stroke:cyan" vector-effect="non-scaling-stroke" class="sc-htoDjs hCHUAb"><circle cx="32" cy="32" r="32" fill="#000" stroke="none"></circle><circle cx="32" cy="32" r="30" stroke-width="1" vector-effect="non-scaling-stroke" opacity="0.5"></circle><g><circle cx="32" cy="32" r="24" stroke-width="2" vector-effect="non-scaling-stroke" class="sc-dnqmqq gAExgp"></circle><circle cx="32" cy="32" r="24" stroke-width="2" vector-effect="non-scaling-stroke" class="sc-iwsKbI PwswZ"></circle></g><text x="32" y="34" text-anchor="middle" font-family="system-ui, sans-serif" font-weight="bold" font-size="4" stroke="none" fill="white" style="text-transform:uppercase;letter-spacing:0.5em">Rebass</text></svg>