JT's Scribblings

a.k.a. a blog of some description.

Shiny stuff with SVG, part 4: Primitives I

Sunday October 28th 2012, at 8:58 pm

Now that I've covered the very basics of filters and how to combine primitives together, the next few posts will be going through all the available primitives describing what each does in turn. The order in which I do them may be a bit arbitrary, but it should roughly start out with the simpler ones you're likely to use most often before moving onto the more technical or obscure ones. This time it'll be feFlood, feOffset, feImage and feTile.

feFlood

The function of the feFlood primitive is simple: fill the entire area with a given colour. The flood's colour and opacity are specified using the flood-color and flood-opacity attributes respectively. The area to fill can be specified using the x, y, width, and height attributes.

If no bounding parameters are specified, the flood area is construed to extend infinitely, so using it as input to primitives like feMorphology or feOffset (covered later) which intrinsically require some kind of boundary, will be ineffectual.

When used on its own, feFlood is rather boring:

<svg>
  <defs>
    <filter id="flood-1">
      <feFlood flood-color="#00f" />
    </filter>
  </defs>
  <circle cx="50" cy="50" r="50" fill="#0f0" filter="url(#flood-1)" />
</svg>

Note that although the filter was applied to a <circle>, the output appears as a square. This demonstrates how the unspecified output of feFlood is not constrained by any input, but instead is only clipped by the filter's bounds (though it in fact extends beyond this boundary too).

The feFlood primitive becomes more useful when combined with other primitives such as feComposite. It's a bit of a simplified example, but we could modify the above example to constrain the flood to the circle, using an feComposite with in as the operator:

<svg>
  <filter id="flood-2">
    <feFlood flood-color="#00f" />
    <feComposite in2="SourceGraphic" operator="in" />
  </filter>
  <circle cx="50" cy="50" r="50" fill="#0f0" filter="url(#flood-2)" />
</svg>

feOffset

feOffset is another easy one to get your head around. It simply takes its input and translates it by an offset given by the dx and dy attributes. Here's a super-simple example.

<svg>
  <defs>
    <filter id="offset" width="250%" height="250%">
      <feOffset dx="60" dy="60" />
      <feComposite in="SourceGraphic" />
    </filter>
  </defs>
  <rect width="40" height="40" fill="#395" filter="url(#offset)" />
</svg>

It's worth noting that if the output of the feOffset lies entirely outside the filter's bounds (specified by the x, y, width and height on the filter element itself), it may well cause a silent error, causing the filter to break and the element not to be rendered at all (for example, in the above example, without setting width and height to 250% on the filter, the result would have been an entirely empty SVG).

feImage

The purpose of the feImage primitive is quite simply to load an external image into the filter, which can then be used for further manipulation. The image can have x, y, width and height properties to determine its geometry.

The URL of the image to use is specified by the xlink-namespaced href attribute.

For example:

<svg>
  <defs>
    <filter id="img">
      <feImage xlink:href="smiley.png"
               x="0" y="0" width="100" height="100" />
    </filter>
  </defs>
  <rect x="0" y="0" width="100" height="100" filter="url(#img)" />
</svg>

As you can probably tell, I'm not an artist.

Obviously on its own, feImage is a bit pointless, but the purpose of it is to bring in external images for use in other filter primitives, with which you can do much more powerful stuff.

It's also worth noting that by default the image's aspect ratio is preserved. The feImage element has preserveAspectRatio property that behaves in exactly the same way as the corresponding property on an <image>.

feTile

The feTile primitive takes another primitive as input and repeats it both horizontally and vertically within the rectangle specified by its x, y, width and height parameters.

<svg>
  <defs>
    <filter id="tile">
      <feImage xlink:href="smiley.png"
               width="30" height="30" x="0" y="0" />
      <feTile x="10" y="10" width="80" height="80"/>
      <feComposite in2="SourceGraphic" />
    </filter>
  </defs>
  <rect width="100" height="100" filter="url(#tile)" />
</svg>

Note that the x and y parameters do not change the positioning of the tiled image itself, merely the rectangle to which the layer is clipped.

The displacement between repeated instances depends on the region specified by the input primitive. So in the example above, the image is repeated every 30 pixels both horizontally and vertically because the width and height of the image are both set to 30.

That's all for this time

The next post will cover feColorMatrix, feGaussianBlur and feMorphology, and will demonstrate how to combine some of these primitives to produce effects such as drop shadows.

Other Posts in This Series

Useful Links