Scale почему-то изменяет координаты

Есть анимация трансформации:

<use xlink:href="#heart" fill="crimson" transform="scale(1)" x="580px" y="200px">
    <animateTransform attributeName="transform" type="scale" from="1" to="2" dur="5s" repeatCount="indefinite" />
</use>

И вот эта анимация почему-то меняет еще и положение элемента(точнее скейлит ещё и координаты). Как? Почему? Как фиксить?


Ответы (1 шт):

Автор решения: Alexandr_TT

Координаты фигур в SVG рассчитываются от верхнего левого угла холста SVG
Представьте, что ваша фигура сердце обведена прямоугольником. X,Y координаты - расстояние левого, верхнего угла этого прямоугольника от левого верхнего угла холста SVG.

Допустим x="30", тогда при увеличении scale(2) размер станет x="60" Поэтому увеличенная фигура сдвинется вправо и вниз.
Чтобы вернуть фигуру на прежнее место необходимо использовать команду
translate="(-30,-30)"

В CSS это можно сделать несколько проще, используя transform-box

#heart {
transform-origin: center, center;
transform-box: fill-box; 
transform: scale(2); 
}

Пример анимации CSS

#heart {
transform-origin: center;
transform-box: fill-box; 
fill:crimson; 
animation: scale1 5s linear forwards infinite;
}

 @keyframes scale1 {
  	100% {
  		transform: scale(2);
  	}
  }
<svg xmlns="http://www.w3.org/2000/svg"   width="400" height="400" viewBox="0 0 1000 1000" style="border: solid;">
<defs>
<path id="heart"    d="M340.8,98.4c50.7,0,91.9,41.3,91.9,92.3c0,26.2-10.9,49.8-28.3,66.6L256,407.1L105,251.6c-15.8-16.6-25.6-39.1-25.6-63.9 c0-51,41.1-92.3,91.9-92.3c38.2,0,70.9,23.4,84.8,56.8C269.8,121.9,302.6,98.4,340.8,98.4" >
    <!-- <animateTransform attributeName="transform" type="scale" values="1;2" dur="5s" repeatCount="indefinite" />  -->
</path>
</defs>
 <use id="u1" xlink:href="#heart" fill="crimson"  x="250px" y="250px"/> 
</svg>

Пример анимации SVG

Паузы в крайних положениях достигаются повторением атрибутов values="1;2;2;1;1"

#heart {
transform-origin: center;
transform-box: fill-box; 
fill:crimson; 
}
<svg xmlns="http://www.w3.org/2000/svg"   width="400" height="400" viewBox="0 0 1000 1000" style="border: solid;">
<defs>
<path id="heart"    d="M340.8,98.4c50.7,0,91.9,41.3,91.9,92.3c0,26.2-10.9,49.8-28.3,66.6L256,407.1L105,251.6c-15.8-16.6-25.6-39.1-25.6-63.9 c0-51,41.1-92.3,91.9-92.3c38.2,0,70.9,23.4,84.8,56.8C269.8,121.9,302.6,98.4,340.8,98.4" >
    <animateTransform attributeName="transform" type="scale" values="1;2;2;1;1" dur="5s" repeatCount="indefinite" /> 
</path>
</defs>
 <use id="u1" xlink:href="#heart" fill="crimson"  x="250px" y="250px"/> 
</svg>

В качестве бонуса

Анимация разбитого сердца

Для начала анимации кликните по сердечку

<svg id="heart" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200" viewBox="0 0 100 100">
<style>
#right-half, #left-half{
 fill:#dc143c;
 }
</style> 
<title> to break heart</title>
<desc>animation icons svg-art.ru - broken heart</desc>
 <g>
  <path id="right-half"  d="M63.9 24C58.5 24 53.5 27 50.2 32.5 49.8 35.3 50.5 40.6 50.5 40.6L48.8 45.2 53.8 49.7 47.6 55.5 54 57.8 49.8 61.6C49.7 69.1 50.2 69 50.1 75.4 50.1 75.4 50.2 75.7 50.2 75.7 50.6 75.7 51 75.5 51.1 75.1 53 70.1 58 66.3 63.4 62.2 70.9 56.5 78.6 50.7 79.2 41.1 79.4 36.4 77.9 32 74.8 28.8 73.5 27.4 72 26.3 70.4 25.5 68.4 24.5 66.1 24 63.9 24z">
    <animateTransform id="break" attributeName="transform" type="rotate" begin="heart.click" dur="1s" repeatCount="1" values="0 50 75.7;7 50 75.7" fill="freeze" restart="whenNotActive"/>
	   <animateTransform attributeName="transform" type="rotate" begin="break.end+3s" dur="0.5s" repeatCount="1" values="7 50 75.7;0 50 75.7" fill="freeze" restart="whenNotActive"/>
      </path>
 </g>
    <g >
		<path  id="left-half" d="m50.1 75.4c0 0 0.1 0.3 0.1 0.3-0.4 0-0.8-0.3-0.9-0.7-1.9-5.1-7-9-12.4-13-7.3-5.5-14.9-11.2-15.6-20.9-0.3-4.5 1.1-8.8 4.2-12 3-3.2 7.2-5.1 11.5-5.1 5.5 0 10.3 3.1 13.4 8.5-0.4 2.9 0.3 8.1 0.3 8.1l-1.7 4.6 5 4.5-6.2 5.8 6.4 2.4-4.2 3.8c0 7.4 0.4 7.4 0.3 13.7z" >
		  <animateTransform attributeName="transform" type="rotate" begin="heart.click" dur="1s" repeatCount="1" values="0 50 75.7;-7 50 75.7" fill="freeze" restart="whenNotActive"/>
		      <animateTransform attributeName="transform" type="rotate" begin="break.end+3s" dur="0.5s" repeatCount="1" values="-7 50 75.7;0 50 75.7" fill="freeze" restart="whenNotActive"/>
		</path>
	</g>
</svg>

→ Ссылка