以下是 Joni Trythall 的客座文章。Joni 最近完成了一本 SVG 写作口袋指南。我对 SVG 感兴趣已经有一段时间了,一直在使用它、学习它、写它……但还有很多东西需要学习。它确实是网络的另一个全新领域。因此,我联系了 Joni,看看她是否愿意为 CSS-Tricks 撰写关于 SVG 的文章,她同意了!以下是 Joni 关于 SVG 中的灯光效果的文章,我知道我在读这篇文章之前对此一无所知。
SVG 有自己的一套 滤镜效果,当 编写 SVG 时,允许作者组合其中一些效果并将滤镜应用于图形。
SVG 过滤的一些更奇妙的功能围绕着 光源。您可以将灯光效果应用于 SVG,然后通过三种滤镜效果之一来控制该效果的细节:fePointLight
、feDistantLight
和 feSpotLight
。
这些光源滤镜允许一些特别酷的功能。看看这个闪亮的、有灯光的苹果(与没有灯光的苹果相比)
查看 CodePen 上 Joni Trythall (@jonitrythall) 的 7d39edca68f2d2b2dfe0e7f3728a276a。
在这篇文章中,我们将回顾 SVG 滤镜的基本语法,深入研究一些更常见的属性,查看光源效果选项,然后通过一个 SMIL 动画实验将所有内容整合在一起。
filter 元素
SVG 滤镜细节位于 <filter>
元素内。一个 <filter>
由几个不同的效果组成,然后这些效果都被应用于图形元素(如矩形,<rect>
)或容器元素(如组,<g>
)。
<svg>
<defs>
<filter id="apples">
< (filter effect) />
< (filter effect) />
</filter>
</defs>
<rect filter="url(#apples)" />
</svg>
选择属性
虽然有很多与滤镜相关的属性,但我们将特别关注在整个苹果演示中使用的属性。
以下属性,除了 in
之外,可以在任何 SVG 滤镜效果中使用。
x, y
滤镜中的 x
和 y
属性设置滤镜将发生的区域在相应轴上的最小坐标。
result
result
属性为特定滤镜效果分配一个名称。然后可以通过另一个效果的 in
属性来引用该效果。这两种效果必须位于同一个 <filter>
中,它允许我们将几个滤镜效果组合成一个应用于图形。
result
值不是必需的,但在希望重用特定效果时很有用。虽然它的目的与 id
非常相似,但 result
值仅在同一个 <filter>
元素内有用,因此在文档的任何其他地方都无法访问。
in
in
属性指定特定滤镜效果的输入。这里有 七个值选项,包括我们上一节中讨论的 result
的名称,但可能最常引用的两个是 SourceGraphic
和 SourceAlpha
。
如果 in
属性未指定,并且滤镜效果是 <filter>
中列出的第一个效果,则它将默认为 SourceGraphic
。或者,如果该属性未指定,并且不是列出的第一个效果,则默认值将继承之前效果的值。
SourceGraphic
值在in
中将滤镜的输入设置为所应用图形元素的 RGB 颜色。SourceAlpha
与SourceGraphic
具有相同的影响,除了将黑色颜色值用于 RGB 通道输入。
以下是在将模糊滤镜应用于两个相同的圆形时这两个值的影响,两个圆形都具有 fill
值 #ED6E46

光源滤镜
现在我们已经熟悉了 SVG 滤镜中使用的一些更常见的属性,让我们关注光源效果。
SVG 照明通过使用 feDiffuseLighting
或 feSpecularLighting
滤镜来访问,这些滤镜根据 Phong 照明模型 (PDF) 的适当分量来建立其计算结果。
漫射光是指照射到表面并向所有方向均匀散射的光,而镜面光是指向特定方向反射的明亮光点。这篇文章中的演示将只关注通过镜面光或 feSpecularLighting
访问的灯光效果,即“让所有东西看起来闪闪发光的光!”。
在此滤镜效果中使用的属性,如 specularConstant
和 specularExponent
,根据 Phong 照明模型计算设置灯光的细节。
以后的基本灯光滤镜相关语法将如下所示
<filter>
<feSpecularLighting>
< (light source effect) />
< (light source effect) />
</feSpecularLighting>
</filter>
让我们看一下将位于此指定计算中的 fePointLight
、feDistantLight
和 feSpotLight
效果。
fePointLight
fePointLight
在应用 feSpecularLighting
滤镜时将特定点设置为主要光源,这也是第一个演示中获得闪亮苹果的方式。
灯光没有到达苹果最边缘的外观是由 feGaussianBlur
效果的值创建的,这里的值越大,混合效果就越强。
x, y, z
这里的 x
、y
和 z
属性确定光源在相应轴上的坐标系中的位置。z
将通过确定光点到用户之间的位置来调整光点的感知大小;这里的值越大,光点就越大,“更靠近”用户。
feDistantLight
feDistantLight
定义一个远光源。
feDistantLight
中的azimuth
属性定义光源在 XY 平面上的顺时针方向角(以度为单位)。elevation
中的值定义光源从 XY 平面到 z 轴的方向角(以度为单位)。
下面苹果上的滤镜具有 azimuth
值 25px
和 elevation
值 40px
查看 CodePen 上 Joni Trythall (@jonitrythall) 的 9be1624ee991e2978a922ac39b8bb029。
feSpotLight
feSpotLight
定义了一个聚光灯作为光源。
x
、y
和z
值在坐标系中确定光源沿相应轴的位置。limitingConeAngle
通过不允许光线在它之外渲染,限制了光线投射的区域。此值设置聚光灯轴与锥体之间的角度(以度为单位)。这里的值越大,限制的区域越小。
下面的 feSpotLight
滤镜包含以下规范:x="400" y="400" z="900" limitingConeAngle="9"
查看 195ed2b4fa8f17b0f8145b9384116a44,由 Joni Trythall (@jonitrythall) 在 CodePen 上创建。
动画光源
光源也可以进行动画处理。当在内联中使用时,此图形的代码非常复杂且冗长,但为了科学起见,我们将让太阳从苹果树的一侧移动到另一侧,充当“光源”。
查看 Apple Tree Lighting Animation,由 Joni Trythall (@jonitrythall) 在 CodePen 上创建。
太阳(即我们假装的光源)通过 SMIL 动画 在屏幕上移动。相应地,树上的光源滤镜也会随着太阳位置的变化而进行动画处理。
每个要进行动画处理的元素都需要一个 <animate>
元素,它们都在 HTML 中都有说明。
结论
SVG 光源滤镜确实可以使图形在屏幕上栩栩如生,测试了该语言二维限制的边界。这些高级功能使我们能够创建更复杂、更详细的图像,这些图像存在于 DOM 中,可以轻松地进行交互或编写脚本。
这里讨论的照明细节实际上只是触及了 SVG 滤镜功能的表面,但希望我们所审查的内容能激发你对其进行研究并探索其全部潜力。
在这篇文章中,我们回顾了一些基本的 <filter>
语法,查看了一些属性,重点关注了一些巧妙的灯光效果,然后以科学的名义对这些效果进行了动画处理。
编辑注:请务必查看 Joni 的 Pocket Guide to Writing SVG。
我的 Android 浏览器没有效果 :S
该升级了:caniuse 表示,从 Android 4.4 开始支持 SVG 滤镜。
适用于 Chrome for Android
太棒了!我在 Chrome for Android 中看到了所有效果。
如果没有 IE,这个世界会多么美好。十五年后,我们将看到 SVG 滤镜效果……
不是开玩笑。
浏览器支持如何?
从技术上讲,浏览器支持非常强,不过我承认,我经常会在不同浏览器中遇到高级 SVG 功能的奇特问题,这些问题从技术上讲是没有意义的
我不知道 SVG 的灯光效果能做这么多!太棒了!
令人印象深刻,@Joni Trythall… 动画光源演示太棒了。感谢分享!
太不可思议了
非常有用,但哪些浏览器支持它?
现在在考虑如何创建一个可以应用于页面上各种对象的滤镜。实质上是在页面界面上添加一个 CSS 光源,以实现 3D 效果。
– 或者跟随鼠标(在实际页面上可能会很烦人,所以只是为了概念验证)
– 或者在滚动时保持页面位置的光源(或视差)。