SVG marker element
Jakob Jenkov |
SVG markers are used to mark the start, mid and end of a line or path. For instance, you can have a circle or square mark the beginning of the path, and an arrow head mark the end of the path.
Marker Example
Here is a simple visual example of how markers can look:
Markers are created using the <marker>
element. The <marker>
element has to be nested inside a <defs>
element. The <defs>
element normally
holds a set of reusable definitions for the SVG image.
Here is the SVG code for the previous example:
<defs> <marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5"> <circle cx="5" cy="5" r="3" style="stroke: none; fill:#000000;"/> </marker> <marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto"> <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" /> </marker> </defs> <path d="M100,10 L150,10 L150,60" style="stroke: #6666ff; stroke-width: 1px; fill: none; marker-start: url(#markerCircle); marker-end: url(#markerArrow); " />
First of all, notice the <defs>
element with the two <marker>
elements inside. The two <marker>
elements define the start and end markers shown
in the previous image.
Second, notice how the <path>
element references the two <marker>
elements from inside its style
attribute, using the marker-start
and
marker-end
CSS properties. This is how you specify what markers to use for a given path.
I will get back to that a little later.
Defining a Marker
You define a marker using the <marker>
element. Here is an example:
<marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5"> <circle cx="5" cy="5" r="3" style="stroke: none; fill:#000000;"/> </marker>
This example defines a marker with a width of 8 (markerWidth="8"
), a height of 8
(markerHeight="8"
). The width and height are necessary to set explicitly, since
the marker is a separate graphic element.
The id
attribute of the <marker>
element is used to
reference this marker from <path>
elements.
The refX
and refY
coordinates sets which point inside the marker
is to be used as reference point. The reference point is what is positioned at the beginning
of the path using the marker. In this example refX
and refY
are set to the center of the circle, meaning the center of the circle will be placed at
the beginining of the path. If you do not set refX
and refY
they
will be assumed to be 0, which will put the upper left corner of the marker at the beginning
of the path.
Inside the <marker>
elements is a <circle>
element.
The circle element is defined with a center (cx
and cy
) at 5,5
.
The center point is the center within the markers virtual box. It is not the location where it is actually placed on the image.
The virtual box is set to 8,8 in size in the
<marker>
element using markerWidth
and markerHeight
.
Auto Orientation
Here is another <marker>
definition example. This example defines the triangle
used as arrow head for the path.
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto"> <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" /> </marker>
The <path>
inside the <marker>
element draws a triangle with
the tip pointing to the right. However, if the path is not a horizontal line, you need the triangle
to be rotated so it fits the direction of the path that uses it. You do so by setting the orient
attribute to auto
. That will rotate the shape inside the <marker>
element
to fit the path that references it.
Here is an image showing five lines with different slopes, all using the same two markers as start and end markers. Notice how the markers are automatically rotated to fit the slope of the line which they are used on.
That is the result of setting the orient
attribute to auto
in
the <marker>
element.
You can also set the value of the orient
attribute to a fixed number of degrees (e.g. 45
).
That will rotate the marker by that degrees when used. This is not nearly as useful as the auto orientation feature though.
Referencing a Marker From a Path
You can reference a marker from a path using these CSS properties:
marker-start
marker-mid
marker-end
These three CSS properties assign a marker to the start, mid-point and end of a path.
The CSS properties have to be located inside the style
attribute of the
<path>
element using them. You reference a <marker>
element by referencing its id
attribute like this:
marker-start : url(#markerId);
The markerId
should be replaced by the value of the id
attribute
of the <marker>
element to reference.
Here is an example using all three CSS properties:
<defs> <marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4" orient="auto"> <rect x="1" y="1" width="5" height="5" style="stroke: none; fill:#000000;"/> </marker> <marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="7" orient="auto"> <path d="M2,2 L2,13 L8,7 L2,2" style="fill: #000000;" /> </marker> </defs> <path d="M100,20 l50,0 l0,50 l50,0" style="stroke: #0000cc; stroke-width: 1px; fill: none; marker-start: url(#markerSquare); marker-mid: url(#markerSquare); marker-end: url(#markerArrow); " />
This is the resulting image:
Referencing a Marker From Other Shapes
The <path>
element is not the only SVG element that can use markers. The
<line>
, <polyline>
and <polygon>
elements
can use markers too. They do so in the exact same way the <path>
element does
this: By referencing the <marker>
element's id
attribute in their
marker-start
, marker-mid
and marker-end
CSS properties.
Marker Units
The size of the marker can be set to scale to fit the stroke width of the path using it. Here is a visual example:
You achieve this effect by setting the markerUnits
of the <marker>
element
to strokeWidth
. This is actually the default value for that attribute, so even if you do not
set the markerUnits
attribute, this is the default behaviour. Here is how it looks in SVG code:
<marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4" orient="auto" markerUnits="strokeWidth"> <rect x="1" y="1" width="5" height="5" style="stroke: none; fill:#000000;"/> </marker>
To avoid the automatic scaling of markers to fit the stroke width of the path using it, set
the markerUnits
attribute to userSpaceOnUse
. That way the markers will
keep their size regardless of the stroke width of the path using it.
Tweet | |
Jakob Jenkov |