假设我有一个div,其中有两个SVG元素:svgPlan***和***svgIcon(这是一个SVG图像元素)。
服务计划:
svgIcon:
一组转换(透视、rotateX、缩放***和***平移)应用于父元素**(svgPlan)**:
svg.style('transform', 'perspective(30em) rotateX(33deg) scale(1.7) translate(0%, -6%)');
转换后的svgPlan:
我要在***svgPlan***内显示***svgIcon***。
问题:转换同时应用于父元素svgPlan和子元素***svgIcon***。子元素似乎自动继承了应用于父元素的样式,但这不是我所希望的。我希望图标显示时没有任何效果。
问题:我如何取消继承父元素的样式(我认为目前在SVG上是不可能的),或者应用***逆变换***使图标显示时没有任何透视或样式?
指令集
最小可重现示例:
<div>
<svg id="svgPlan" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 2118.5 624.2" enable-background="new 0 0 2118.5 624.2" xml:space="preserve"
style="transform:perspective(30em) rotateX(30deg) scale(1.17)">
<rect width="1200" height="400" style="fill:rgb(224,224,224);stroke-width:3;stroke:rgb(0,0,0)" />
<g id="svgIcon">
<image x="550" y="120" width="120" height="120" xlink:href="https://svgshare.com/i/npz.svg">
</image>
</g>
</svg>
</div>
谢谢你的帮助。
2条答案
按热度按时间lo8azlld1#
这个答案提出的解决方案与SVG没有太大关系,相反,它使用了更通用的方法,将CSS的透视转换专门应用于HTML元素-其中一些元素可能是SVG图像,也可能包含SVG图像。
先说些琐事:
z-index
,层只是由源(DOM)的外观顺序表示。SVG在本质上实际上只是一个“平面”二维矢量图形。rotate3d
、translate3d
、rotatex()
等,因此它们没有任何效果。<div>
,也可以只是HTML<img>
-在所有情况下,这些都只是“视口”矩形,在无限(可能经过转换)平面内显示(SVG)内容。据我所知,您的用例是在某个倾斜的图像上方显示标记图标(如“精灵”),这些图标始终面向摄像头(说一个“Map”)。从你的问题中不清楚遥远的图标是否(离摄像头较远的)应较小,并与较近的重叠(什么感觉更自然,但与“非继承”的立场相矛盾)或者每个都是相同的大小,具有未定义的重叠策略。
在“HTML”世界中,您可以嵌套转换后的元素,并让子元素与父元素一起移动(借助
transform-style: preserve-3d;
),以使它们到达所需的位置,然后将否定转换应用于它们的子元素,使这些子元素再次面向相机。让我们从基本的纯SVG平面图像开始-带有两个“标记”的“Map”概览,没有转换:
(我已经将图像图标提取为简化的dataURI,并将位置更改为分组转换,以提高可重用性和独立性。)
现在让我们来介绍一下斜坡和图标“sprites”。
<img>
。<img>
都被定位并转换到Map上的相应位置。这里的自定义属性有助于重用性,但静态值也可以硬编码。--slope
和calc
也简化了“自动化”,并允许从范围输入启动更改。第一次

应该呈现如下内容:
对于单个3D变换,这是合适的;对于多个同时的转换,应该包含更多的数学运算或者嵌套更多的转换 Package 器。2请参阅pen中的example of nested transform layers producing sprite-like "dots" in 3d space使用此技术。
n3h0vuf22#
通过取消
rotateX
,让图标(放在单独的覆盖svg上)在相同的透视投影下面向viewpoint
,可以实现该画面。例如:
但是,由于透视投影,图标上的缩放效果将保持不变。
应用于图标的转换的简要说明
perspective(30em) rotateX(30deg) scale3d(1.17, 1.17, 1.17)
:套用至svgPlan
的转换复本translate3d(calc(100% * 610 / 2118.5 - 50%), calc(100% * 240 / 624.2 - 50%), 0)
:从css转换原点(50%,50%)转译回原始位置(610,240)rotateX(-30deg)
:转换以取消旋转translate3d(calc(-100% * 610 / 2118.5 + 50%), calc(-100% * 240 / 624.2 + 50%),0)
:从图标的底部中心(610,240)到css转换原点(50%,50%)的转换