SVG Привязка растровых объектов к пути (path)

434
12 августа 2021, 00:00

Не могу найти информацию по привязке объекта к пути.

Имеется следующий элемент SVG:

svg{ 
  width: 500px; 
  height: 500px; 
} 
svg path{ 
  fill: none; 
  stroke: red; 
  stroke-width: 5px; 
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> 
    <path id="curve" d="M64,287 C277,329 191,140 445,210" /> 
    <text style="font-size: 24px;"> 
        <textPath xlink:href="#curve" startOffset="50%" text-anchor="middle">test text</textPath> 
    </text> 
    <image href="https://img.icons8.com/ios-filled/50/000000/user-male-circle.png" rx=5 width="50px" height="50px"> 
        <animateMotion 
            dur="5s" 
            repeatCount="3" 
            rotate="auto" 
            restart="whenNotActive"> 
            <mpath xlink:href="#curve" /> 
        </animateMotion> 
    </image> 
</svg>

Создал своего франкенштейна из ответов на SO, где нашел текст привязанный к пути и картинку, которая привязана только по анимации.

Задача состоит в том, чтобы просто привязать объект image к пути подобно тексту. Но гуглежка в течении часа не дала плоды и поэтому я задаю этот вопрос здесь.

Answer 1

Можно сделать keyPoints в одной и той же точке, вот что получается:

svg{ 
  width: 500px; 
  height: 500px; 
} 
svg path{ 
  fill: none; 
  stroke: red; 
  stroke-width: 5px; 
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 160 500 500"> 
    <path id="curve" d="M64,287 C277,329 191,140 445,210" /> 
    <text style="font-size: 24px;"> 
        <textPath xlink:href="#curve" startOffset="50%" text-anchor="middle">test text</textPath> 
    </text> 
    <image href="https://img.icons8.com/ios-filled/50/000000/user-male-circle.png" width="50px" height="50px" transform="translate(-25,-25)"> 
        <animateMotion calcMode="linear" keyPoints="0.5; 0.5" keyTimes="0; 1" rotate="auto"> 
            <mpath xlink:href="#curve" /> 
        </animateMotion> 
    </image> 
</svg>

PS: я так же на 50% подвинул изображение влево и вверх

Answer 2

Для того, чтобы привязать картинку к пути, можно воспользоваться маркерами

В роли маркера может выступать любая фигура SVG и в том числе любое растровое изображение.

 <marker id="User" viewBox="0 0 50 50" refX="0" refY="27"
        markerUnits="userSpaceOnUse"  orient="auto"
        markerWidth="50" markerHeight="50" > 
        <image href="https://i.stack.imgur.com/76W3b.png"  width="50px" height="50px"/>
    </marker>   

Маркеры имеют три места посадки на линию:

marker-start, marker-mid, marker-end
Если нужно разместить маркер на середине линии, то выбираем - marker-mid Также необходимо учитывать, что такого наименования маркеры размещаются на переломных точках и их может быть несколько.

refX="0" refY="27" - атрибуты для позиционирования маркера относительно path

<style> 
svg{ 
  width: 500px; 
  height: 500px; 
} 
svg path{ 
  fill: none; 
  stroke: red; 
  stroke-width: 5px; 
} 
</style> 
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> 
  <defs> 
    <marker id="User" viewBox="0 0 50 50" refX="0" refY="27" 
        markerUnits="userSpaceOnUse"  orient="auto" 
        markerWidth="50" markerHeight="50" >  
		<image href="https://i.stack.imgur.com/76W3b.png"  width="50px" height="50px"/> 
	</marker>	 
  </defs> 
    <path id="curve" d="M64 287C170.5 308 202.3 271.3 239.1 238 276 204.8 318 175 445 210" marker-mid="url(#User)" /> 
    <text dy="-5" style="font-size: 28px;"> 
        <textPath xlink:href="#curve" startOffset="40%" text-anchor="middle" >test</textPath> 
    </text> 
	 <text dy="-5" style="font-size: 28px;"> 
        <textPath xlink:href="#curve" startOffset="65%" text-anchor="middle" >text</textPath> 
    </text> 
     
</svg>

  • Допустим не устраивает нас красная линия на заднем фоне.

    Можно усложнить маркер и сделать картинку непрозрачной, для этого добавим на задний фон непрозрачную окружность <circle cx="25" cy="25" r="25" fill="white" />

  • Или нужно увеличить размер изображения

    Для этого увеличиваем регион действия маркера:

    markerWidth="70" markerHeight="70"

<style> 
svg{ 
  width: 500px; 
  height: 500px; 
} 
svg path{ 
  fill: none; 
  stroke: red; 
  stroke-width: 5px; 
} 
</style> 
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> 
  <defs> 
    <marker id="User" viewBox="0 0 50 50" refX="0" refY="27" 
        markerUnits="userSpaceOnUse"  orient="auto" 
        markerWidth="70" markerHeight="70" >  
		 <circle cx="25" cy="25" r="25" fill="white" /> 
		<image href="https://i.stack.imgur.com/76W3b.png"  width="50px" height="50px"/> 
	</marker>	 
  </defs> 
    <path id="curve" d="M64 287C170.5 308 202.3 271.3 239.1 238 276 204.8 318 175 445 210" marker-mid="url(#User)" /> 
    <text dy="-5" style="font-size: 28px;"> 
        <textPath xlink:href="#curve" startOffset="40%" text-anchor="middle" >test</textPath> 
    </text> 
	 <text dy="-5" style="font-size: 28px;"> 
        <textPath xlink:href="#curve" startOffset="70%" text-anchor="middle" >text</textPath> 
    </text> 
     
</svg>

READ ALSO
Выполнение функции только если найден элемент на странице

Выполнение функции только если найден элемент на странице

Есть основной код который должен выполняться

122
Не отображается содержимое и сам элемент &lt;script&gt; во вкладке Elemets

Не отображается содержимое и сам элемент <script> во вкладке Elemets

Изучая туториал по react столкнулся с проблемой после подключения

101
C# webBroser .DocumentText возвращает исходный код только первой страницы

C# webBroser .DocumentText возвращает исходный код только первой страницы

Пытаюсь спарсить несколько страницДобавил элемент WebBrowser и кнопку, на ее нажатие поставил событие

183