0

I have a curved svg line like this

<path d="M70,260 C105,260 126,330 160,330"  
    style="stroke: #ff4444;stroke-width:2; fill:none;"/>

what I want is to add another svg (like https://www.flaticon.com/free-icon/play-button_149657) in the middle of my line pointing to the end point.

any ideas?

2 Answers2

2

One way to achieve the result is a degenerate animation:

  • Define the marker shape (obj1 in the example below)
  • Position the marker at the beginning of the curve (track1 below; this is the path definition from your example).
  • Specify an animated motion of the marker shape along the curve with some particular settings:

    • Explicit positioning along the track using keyTimes, keyPoints attributes, limiting the range of positions to exactly one point: the midpoint of the curve
    • Infinite duration, infinite repeat
    • Auto-rotation of the shape according to the orientation of the track curve ( rotate attribute )

Effectively there is no animation at all but the shape is positioned at the center of the curve, properly oriented.

Example

<html>
    <head>
        <title>SVG object centered on path</title>
    </head>
    <body>
        <svg width="200px" height="200px"
            viewBox="0 0 500 500"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
        >
            <defs>
                <path
                    id="obj1"
                    d="M11.18,0 L-2.5,10 -2.5,-10 Z"
                    stroke="black" stroke-width="1" fill="green"
                >
                </path>
                <path
                    id="track1"
                    d="M70,260 C105,260 126,330 160,330"
                    stroke="#ff4444" stroke-width="2" fill="none"
                />
            </defs>
            <use xlink:href="#track1"/>
            <use xlink:href="#obj1">
                <animateMotion
                    calcMode="linear"
                    dur="infinite"
                    repeatCount="infinite"
                    rotate="auto"
                    keyPoints="0.5;0.5"
                    keyTimes="0.0;1.0"
                >
                    <mpath xlink:href="#track1"/>
                </animateMotion>
            </use>
        </svg>
    </body>
</html>
collapsar
  • 17,010
  • 4
  • 35
  • 61
  • cool, works fine. do you know if I can also use something like that as a google maps marker? as far as I know, on the marker you can only use the path as icon – Giannis Tzagarakis Feb 14 '18 at 08:32
1

There are a number of ways to do this.

One way is to "cheat" a little and use a <textPath> and an arrow character.

SVG marker-mid on specific point on path

This is a little hacky, and may not work reliably on all browsers, but it may be good enough for your needs.

Another way is split the path in two (using De Casteljau's algorithm), and use a <marker>.

<svg viewBox="0 200 200 200" width="400">
  <defs>
    <marker id="Triangle"
      viewBox="0 0 10 10" refX="0" refY="5" 
      markerUnits="strokeWidth"
      markerWidth="4" markerHeight="3"
      orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" />
    </marker>
  </defs>

  <path d="M 70,260
           C 87.5,260 101.5,277.5 115.375,295
           C 129.25,312.5 143,330 160,330"  
        style="stroke: #ff4444; stroke-width:2; fill:none; marker-mid:url(#Triangle)"/>
</svg>

There are other ways using Javascript. For example, you could use the SVGPathElement.getPointAtLength() method to find the coordinates of the centre of the path. Then position a triangle at that location.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181