Units in conflict

The filter element has a region, an area in which the result of the nested functions, so-called primitives, shows itself.

By default the region considers a rectangle slightly larger than that describing the filtered shapes.

<filter id="fe" x="-10%" y="-10%" width="120%" height="120%">
	<!-- ... -->
</filter>

And you can certainly change the default values, in percentages or with decimal numbers. You could, for instance, double the width.

<filter id="fe" width="2.4">
	<!-- ... -->
</filter>

Why would you care to do that? Perhaps you want to add something on the side of the figure. Think of a copy, right next to an unassuming circle.

<circle filter="fe" r="40" />

You can just repeat the shape, with another <circle>, or again with a <use> element.

<circle id="circle" r="40" /> 
<use href="#circle" x="40" />

But with a filter, you can combine the change with other features, like brilliant light sources.

You can mirror the circle with just two primitives: feOffset and feMerge, but as it is often the case with SVG filters, it is helpful to proceed in increments, one function at a time.

feOffset takes an input, our circle, and moves the visual with the dx and dy attributes.

<feOffset dx="1" />

Setting the horizontal offset to 1 should be enough to move the shape. That being said, the function returns the offset figure, and the offset figure only. We’d like to keep the original circle, and for this, we can use feMerge.

<!-- ...feOffset -->
<feMerge>
	<!-- ... -->
</feMerge>

The primitive introduces another block of elements, but is far from complex. With <feMergeNode> elements you detail the inputs, the shapes you want to unite.

<!-- ...feOffset -->
<feMerge>
	<feMergeNode in="SourceGraphic" />
</feMerge>

In this manner you can keep the original circle, the source graphic, and also include the result of the previous primitive, the previous offsetting function.

<!-- ...feOffset -->
<feMerge>
	<feMergeNode />
	<feMergeNode in="SourceGraphic" />
</feMerge>

Be warned that the order matters. In the snippet the first element does not include the in attribute, and in so doing the input refers to the output of feOffset, to the circle on the side.

The output of feOffset.

<feOffset dx="1" result="offset" />

Is passed implicitly as the input of the first instance of feMergeNode.

<feMerge>
	<feMergeNode in="offset" />
	<feMergeNode in="SourceGraphic" />
</feMerge>

Offset the figure, pair the copy to the original and marvel at the result. Not quite, however.

Circles slightly offset <feOffset dx="1" />

Not by a long margin. What you find with the code is the circle, and seemingly the single, round shape.

In rather philosophical terms:

the filter has its units, of which primitives know not

Down to earth, the units set on the parent element are relative to the final area. This is the default option set through the filterUnits attribute, set to objectBoundingBox.

<filter
	id="fe"
	filterUnits="objectBoundingBox"
	width="2.4"
>
	<!-- ... -->
</filter>

The units of the nested primitives, unfortunately, do not share the same trait. The primitives work in the same coordinate system of the circle, and since the element has a radius of 40 units, the copy is offset by a portion of the same length — you might have noticed that the copy was indeed present, slightly protruding to the right. This is the default behavior and is set through primitiveUnits, set to userSpaceOnUse.

<filter
	id="fe"
	filterUnits="objectBoundingBox"
	primitiveUnits="userSpaceOnUse"
	width="2.4"
>
	<!-- ... -->
</filter>

It is unfortunate that the two attributes don’t match, but it is fortunate that you can change their values to reconcile the system.

<filter
	id="fe"
	filterUnits="objectBoundingBox"
	primitiveUnits="objectBoundingBox"
	width="2.4"
>
	<!-- ... -->
</filter>

Set primitiveUnits on the single <filter> element and the change ripples through the entire sequence. Enough to fix our overlap.

Circles clearly offset primitiveUnits="objectBoundingBox"

And enough to celebrate with a festive decoration. Provided with enough material and space.

A luminous garland