SVG元素上的3D变换

15
在SVG元素上使用3D变换是否能实现透视效果?我指的是类似于《星球大战》片头字幕的3D效果。以下是一个使用CSS3 3D变换实现所需效果的JSFiddle示例:http://jsfiddle.net/rft762u6/1/

<section style="transform: perspective(200px) rotateX(-30deg); transform-origin: 50% 100%; text-align: justify; width: 100px;">
  <p style="backface-visibility: hidden;">TEXTTEXTTEXT</p>
</section>

2个回答

20

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>


14
“3D transforms aren't supported on SVG elements” 这句话非常有用,我希望早一个小时就能找到它。 - spro
1
Firefox现在在大多数情况下(即不在图案或蒙版中)支持SVG元素上的3D变换。 - Robert Longson
1
这里需要注意的是:SVG通过“转换”属性支持等距三维变换,使用旋转和缩放函数进行支持。例如:rotate(45, 50, 50) scale(1,0.5),其中50,50是图形的中心点。 - hardyVeles
现在看来,"SVG元素不支持3D变换"这种说法并不完全正确。例如,可以在<svg>元素内的<circle>元素上应用以下rotate3d动画(仅在Chrome中测试):https://codepen.io/anon/pen/MPeyEj - trusktr
1
@trusktr 它在最新的 FF 上也可以工作。我可能需要更新这个答案。 - web-tiki

5

支持在<svg>元素内部进行3D变换(例如在<circle>上)(至少在某种程度上,透视似乎只是等距的)。

例如,这里是应用于<circle>元素的transform: rotate3d动画(仅在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>

此代码还可以在这里查看:https://codepen.io/anon/pen/MPeyEj


3
有没有其他人在使用trusktr的SVG图像时遇到延迟的情况?(附注:我正在使用Chromebook,所以对于大多数人来说可能不太可能,因为大多数人都在使用更大更强的电脑)我已经检查了代码,并未发现导致我的设备延迟的原因。除非是因为3D变换,但这似乎是不合理的。为什么我的设备会出现延迟? - Major_Flux-
@Major_Flux- 看起来这些等角3D变换发生在CPU上,而不是GPU。我看Chrome任务管理器在处理这个动画的选项卡时使用了一些CPU资源,而且没有运行JavaScript,因此CPU使用率只能来源于CSS引擎进行CPU渲染。 - trusktr
这很奇怪:/ 它为什么选择 CPU 而不是 GPU? - Major_Flux-
@Major_Flux- 我的猜测是因为SVG是基于矢量的,它将所有东西都计算为数学线条,而不是实际对几何(顶点)进行变换,但计算出一条平滑的线条,上面会着色像素。这可以在片段着色器中完成吗?也许!也许没有人成功地在GPU上实现SVG所能做的一切?如果是这样,将CPU和GPU渲染混合到一个中是困难的(可能会有性能问题)。 https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-25-rendering-vector-art-gpu - trusktr

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