TESch
TESch

Reputation: 401

SVG: align tip of "marker-end" with end of line

I'm drawing an SVG line with a "marker-end" to make it an arrow. It draws the arrowhead extending beyond the end of the line, making the whole arrow longer, but I would like the whole arrow to be the same length as the original line. That is, the tip of the arrowhead should be at the endpoint of the line. How do I do that?

Making the line shorter to accommodate the size of the arrowhead won't really work. The size of the arrowhead depends on the thickness of the line (which is good), but I don't know the thickness because it can be specified in a style element that's already been written to the SVG document.

In this example, I'd like the the arrowhead entirely inside the square, with its tip at the square's corner, rather than sticking out of the square.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="0" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
            <path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<line marker-end="url(#arrowhead0)" x1="1" y1="1" x2="100" y2="100" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>

Upvotes: 11

Views: 8929

Answers (3)

TESch
TESch

Reputation: 401

Use "marker-start" instead of "marker-end", draw the arrowhead backwards, and swap the line's endpoints.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="0" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
            <path d="M 60 0 L 0 30 L 60 60 z" fill="#800000" /> </marker>
<line marker-start="url(#arrowhead0)" x1="100" y1="100" x2="1" y2="1" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>

Upvotes: 0

Vasiliy Sharapov
Vasiliy Sharapov

Reputation: 1057

Setting the refX atribute to 60 (which I think might be the width of the arrowhead when oriented pointing to the right) seems to fix this issue. Scaling the width seems to be fine, not sure about other attributes.

I am no SVG expert, just found this interesting and played with the attributes until I stumbled upon this solution, so take it with a grain of salt.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="0" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
        <path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
   <marker id="arrowhead1" viewBox="0 0 60 60" refX="60" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
        <path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
   <marker id="arrowhead2" viewBox="0 0 60 60" refX="60" refY="30" markerUnits="strokeWidth" markerWidth="16" markerHeight="10" orient="auto">
        <path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<line marker-end="url(#arrowhead0)" x1="1" y1="1" x2="100" y2="100" stroke="#800000" />
<line marker-end="url(#arrowhead1)" x1="1" y1="100" x2="50" y2="50" stroke="#800000" />
<line marker-end="url(#arrowhead2)" x1="100" y1="1" x2="50" y2="50" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>

Upvotes: 6

Robert Longson
Robert Longson

Reputation: 124179

refX and refY control that so adjust as necessary. E.g.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="44" refY="34" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
            <path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<line marker-end="url(#arrowhead0)" x1="1" y1="1" x2="100" y2="100" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>

Upvotes: 1

Related Questions