我希望能够创建一个在背景中具有(正常)图像的SVG,以及一个不同的较小图像,其中4个“边缘”被移动以创建非矩形形状。认为类似于扭曲的图像来创建透视图。
SVG有可能吗?如果没有,是否可以在CSS中以一种在页面的非固定元素中可见的方式?
我找到了一些CSS透视图,但它使用了X,Y,Z,当我真的只需要在预定义的非平行边框“框”中拟合(扭曲)图像。
答案 0 :(得分:1)
理论上,有一种方法可以使用SVG 1.1创建所需的失真类型。它依赖于<feDisplacementMap>
filter element。
如果您想要浏览它,我会在下面提供示例代码。但是,除了好奇之外,我不会推荐它。从我的测试来看,代码目前只在Chrome(可能还有相关的浏览器)中提供了所需的结果。 Internet Explorer会扭曲图像,但略有不同。实际上我在I.E.中使用稍微不同的代码,但在Chrome中没有。 Firefox不支持使用<feImage>
过滤器元素从SVG导入片段,因此测试用例失败;如果您将地图渐变创建为单独的图像文件,它应该可以工作。还有简单的渲染质量,因为你使用像素操作扭曲了图像。
linearGradient {
color-interpolation:linearRGB;
}
<svg height="400px" width="400px">
<defs>
<linearGradient id="red-grad" x2="0" y2="100%">
<stop offset="0" stop-color="#F00" />
<stop offset="1" stop-color="#000" />
</linearGradient>
<linearGradient id="mask-grad" x2="100%" y2="0">
<stop offset="0" stop-opacity="0" stop-color="white" />
<stop offset="1" stop-opacity="1" stop-color="white" />
</linearGradient>
<mask id="mask">
<rect fill="url(#mask-grad)"
height="100%" width="100%"/>
</mask>
<rect id="red-rect" fill="url(#red-grad)" mask="url(#mask)"
height="100%" width="100%"/>
<filter id="perspective" primitiveUnits="objectBoundingBox"
x="-50%" y="-50%" width="200%" height="200%">
<feImage xlink:href="#red-rect" result="red" />
<feFlood flood-color="black" result="black" />
<feComposite operator="over" in="red" in2="black"
result="map"/>
<feDisplacementMap in="SourceGraphic" in2="map"
yChannelSelector="R"
xChannelSelector="G"
scale="1.1" />
</filter>
</defs>
<g style="opacity:0.5">
<image id="pic" height="100%" width="100%" xlink:href="http://upload.wikimedia.org/wikipedia/commons/thumb/2/24/Iglesia_de_Santiago_Tlatelolco%2C_M%C3%A9xico_D.F.%2C_M%C3%A9xico%2C_2013-10-16%2C_DD_38.JPG/320px-Iglesia_de_Santiago_Tlatelolco%2C_M%C3%A9xico_D.F.%2C_M%C3%A9xico%2C_2013-10-16%2C_DD_38.JPG"
/>
</g>
<g transform="scale(0.7 0.5)skewY(4)">
<use y="25%" xlink:href="#pic" filter="url(#perspective)" />
</g>
</svg>
<p>Image by <a href="http://commons.wikimedia.org/wiki/File:Iglesia_de_Santiago_Tlatelolco,_M%C3%A9xico_D.F.,_M%C3%A9xico,_2013-10-16,_DD_38.JPG">Diego Dielso, via Wikimedia Commons.</a></p>
相反,正如Robert Longson在评论中所建议的那样,最佳方法是使用3D transforms来创建透视效果。大多数浏览器(最新版本)现在支持HTML图像上的3D变换,但您需要使用-webkit-前缀复制声明。
如果您在CSS代码中声明它们,许多浏览器(I.E.是例外)也将支持SVG元素的3D变换。但是,SVG不支持transform-origin
属性;最好将其保留为默认值(SVG坐标系原点,与SVG1.1变换相同),并使用其他变换来获得所需的效果。
对于那些好奇的人说明摘要:
两个渐变,蒙版,矩形和前三个滤镜元素都只是一种创建二维黑色到红色渐变的方法(右上角为红色,左侧和下方为黑色)。这就是IE存在问题的地方 - 不同的元素尺寸不正确,因此大部分图像都是黑色的。我必须将color-interpolation
属性设置为linearRGB
,以便红色通道根据数值平滑增加,而不是经过伽马校正。如上所述,您可以将地图渐变创建为单独的图像文件,并使用单个<feImage>
元素将其导入过滤器,然后Firefox也会支持这种效果。
feDisplacementMap
滤镜元素占据in
图形中的每个像素,并根据in2
图形中相应像素的颜色值移动它(黑色和红色渐变)。 y位移设置为使用地图的红色值,而x位移使用绿色值(对于整个红黑渐变将为零)。
第一个图像元素是半透明背景。
然后将此图像复制到<use>
元素中,并应用过滤器。另外一组变换用于缩放图像并调整整体倾斜(倾斜),使透视变形看起来相当居中。