The following is a guest post by Joni Trythall. Joni recently finished a Pocket Guide to Writing SVG. I’ve been excited about SVG for a while now, working with it, learning about it, writing about it… but there is so much to know. It really is another whole universe of the web. So I reached out to Joni to see if she would like to write something for CSS-Tricks on SVG and she agreed! Here’s Joni on lighting in SVG, something I know I knew nothing about before reading this.
SVG has its own set of filter effects that, when writing SVG, allow the author to combine several of these effects and apply the filter to the graphic.
Some of the more fantastic features of SVG filtering revolve around the light source. You can apply a lighting effect to SVG and then control the details of that through one of three filter effects:
These light source filters allow for some especially neat capabilities. Check out this shiny, lighted apple (as compared to a non-lighted one):
See the Pen 7d39edca68f2d2b2dfe0e7f3728a276a by Joni Trythall (@jonitrythall) on CodePen.
In this post we will review the basic syntax for SVG filters, dive into some of the more common attributes, look at lighting source effect options, and then bring everything together with an SMIL animation experiment.
SVG filter details reside within a
<filter> element. A
<filter> is comprised of several different effects and these effects are then all applied to a graphics element (such as a rectangle,
<rect>) or container element (such as a group,
<svg> <defs> <filter id="apples"> < (filter effect) /> < (filter effect) /> </filter> </defs> <rect filter="url(#apples)" /> </svg>
While there are a great number of filter related attributes, we will specifically be focusing on the ones used here throughout the apple demos.
The following attributes, with the exception of
in, are able to be used within any SVG filter effect.
y attributes within filters set the minimum coordinates on the appropriate axis for the region in which the filter will take place.
result attribute assigns a name to a specific filter effect. This effect can then be referenced by another effect to follow through the
in attribute. Both effects must reside within the same
<filter> and it allows us to combine several filter effects into one to be applied to a graphic.
result value is not required, but is useful when looking to reuse specific effects. While its purpose closely resembles that of an
result values are only useful within the same
<filter> element and are therefore not accessible anywhere else in the document.
in attribute specifies the input for a specific filter effect. There are seven value options here, including the name of the
result which we just reviewed in the previous section, but perhaps the most frequently referenced are
in attribute is left unspecified and the filter effect is the first listed within the
<filter> then it will default to
SourceGraphic. Alternatively, if this attribute is left unspecified and is not the first effect listed, then the default will inherit the value of the effect before it.
insets the input for the filter as the RGB colors of the graphical element to which it is being applied.
SourceAlphahas the same impact as
SourceGraphicexcept black color values are used for the RGB channels input.
Here is a look at the impact these two values have when applying a blurred filter to two identical circles, both having a
fill value of
Lighting Source Filters
Now that we have a familiarity with some of the more common attributes used within SVG filters lets focus on the lighting source effects.
SVG lighting is accessed through the use of
feSpecularLighting filters, which establish its calcluations based on the appropriate component of the Phong lighting model (PDF).
While diffuse light is light that hits a surface and gets scattered equally in all directions, specular light refers to a bright spot of light that gets reflected in a particular direction. The demos throughout this post will only focus on lighting effects accessed through specular light, or
feSpecularLighting, or “light that makes all the things look shiny!”.
Attributes used within this filter effect, such as
specularExponent, set the details of the light based on Phong lighting model calculations.
The basic light filter related syntax going forward will look like this:
<filter> <feSpecularLighting> < (light source effect) /> < (light source effect) /> </feSpecularLighting> </filter>
Let’s take a look at the
feSpotLight effects that will reside within this specified calculation.
fePointLight establishes a specific point as the main light source when applying the
feSpecularLighting filter and is how the shiny apple was achieved in the very first demo.
The appearance of the light not going to the very edge of the apple is created by the value of the
feGaussianBlur effect, and a higher value here would create greater blending.
x, y, z
z attributes here determine the location of the light source in the coordinate system on the appropriate axis.
z will adjust the perceived size of the point of light by determining its location from the point to the user; a higher value here results in a larger point of light that is “closer” to the user.
feDistantLight defines a distant light source.
feDistantLightdefines the clockwise direction angle in degrees for the light source on the XY plane.
- The value within `elevation` defines the direction angle in degrees of the light source from the XY plane towards the z axis.
The filter on the apple below has an
azimuth value of
25px and an
elevation value of
See the Pen 9be1624ee991e2978a922ac39b8bb029 by Joni Trythall (@jonitrythall) on CodePen.
feSpotLight defines a spot light as a light source.
zvalues establish the location of the light source along the appropriate axis within the coordinate system.
limitingConeAnglerestricts the area to which light is projected by disallowing light to render outside of it. This value sets the angle in degrees between the spot light axis and cone. A higher value here results in a less restricted area.
feSpotLight filter below contains the following specifications:
x="400" y="400" z="900" limitingConeAngle="9":
See the Pen 195ed2b4fa8f17b0f8145b9384116a44 by Joni Trythall (@jonitrythall) on CodePen.
Animating Light Sources
Light sources can also be animated. The code for this graphic is fairly complex and lengthy when used inline, but for the sake of science we are going to have the sun moving from one side of the apple tree to the other acting as a “light source”.
See the Pen Apple Tree Lighting Animation by Joni Trythall (@jonitrythall) on CodePen.
The sun, aka our pretend light source, is moving across the screen through SMIL animations. In turn, the light source filter on the tree is also being animated in response to the sun’s positioning.
<animate> element must reside within each element to be animated, which are both noted in the HTML.
SVG light source filters can really bring a graphic to life on the screen, testing the boundaries of the two-dimensional limitations of the language. These advanced features allow us to create more complex and detailed images that live within the DOM and can easily become interactive or scripted.
The lighting details addressed here really only scratch the surface concerning the capabilities of SVG filters, but hopefully what we have reviewed inspires you to tinker with it and explore its full potential.
In this post we reviewed some basic
<filter> syntax, took a look at a few attributes, focused on some neat lighting sources effects, and then animated these effects in the name of science.
Editor’s note: Make sure to check out Joni’s Pocket Guide to Writing SVG.
No effects for my Android browser :S
Time to upgrade: caniuse says that SVG filters are supported as of Android 4.4.
Works for Chrome for Android
This is awesome! I can see all the effects in Chrome for Android.
What a wonderful place the world would be without IE. See you in fifteen years SVG filter effects…
What is the support in browsers?
Browser support is technically very strong, though I will admit that I often hit odd issues with advanced SVG features across browsers that technically make no sense
I didn’t realise so much could be done with light effects and SVG! Incredible!
Impressive ish @Joni Trythall… The animated light sources demo is epic. Thanks for sharing!
very useful but which browers supports it?
Now thinking of how to create a filter that would apply to a variety of objects on a page. Essentially adding a CSS light source for a 3D effect on a page interface.
– Either following the mouse (probably annoying on a real page, so just for proof of concept)
– or light source that holds position on the page while scrolling (or parallax).