Использование CSS-переходов для анимации положения элементов SVG - PullRequest
0 голосов
/ 12 октября 2018

Я хотел бы использовать CSS-переходы для анимации положения элементов SVG.

Однако - похоже, это работает на некоторых элементах SVG (например, прямоугольные), но не на других (например, текст):

document.querySelector("button").onclick = function() {
  var x = Math.random() * 450;
  document.querySelector("rect").setAttributeNS(null, "x", x);
  document.querySelector("text").setAttributeNS(null, "x", x);
}
rect {
  transition: all 700ms ease-in-out;
}

text {
  transition: all 700ms ease-in-out;
}
<svg width="500" height="100">
  <rect x="100" y="10" width="30" height="30" fill="blue" stroke="none"/>
  <text x="100" y="80" fill="red" stroke="none">Hello</text>
</svg>
<br>
<button>animate</button>

Я что-то не так делаю?Есть лучший способ сделать это?(в идеале, без использования JavaScript или такой библиотеки, как GreenSock).

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Вы также можете достичь этого с помощью jquery

$('button').on('click',function(){
    var x = Math.random() * 250;
    $('rect').attr("transform","translate("+x+")");
    $('text').attr("transform","translate("+x+")");
});
rect {
  transition: all 700ms ease-in-out;
}

text {
  transition: all 700ms ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="100">
  <rect x="100" y="10" width="30" height="30" fill="blue" stroke="none"/>
  <text x="100" y="80" fill="red" stroke="none">Hello</text>
</svg>
<br>
<button>animate</button>
0 голосов
/ 12 октября 2018

Правильное решение - использовать transform, как сказал Темани.

Однако в моем реальном приложении элементы SVG движутся под маской, и преобразование, кажется, вызывает непреднамеренную сторону-effects.

Это потому, что преобразование элемента также применяется к другим атрибутам, которые к нему применяются.Такие как маска.Исправление состоит в том, чтобы переместить маску в родительскую группу, чтобы она не влияла на преобразование

<g mask="url(#mask1)">
  <rect id="rect2" x="0" y="60" width="20" height="20" fill="blue" stroke="none"/>
  <text id="text2" x="0" y="100" fill="red" stroke="none">Hello</text>
</g>

Полный пример:

document.querySelector("button").onclick = function() {
  var x = Math.random() * 450;
/*   document.querySelector("rect").setAttributeNS(null, "x", x);
  document.querySelector("text").setAttributeNS(null, "x", x);
   */	
  document.getElementById("rect1").setAttributeNS(null, "x",x);
  document.getElementById("text1").setAttributeNS(null, "x",x);

  document.getElementById("rect2").setAttributeNS(null, "transform","translate("+x+")");
  document.getElementById("text2").setAttributeNS(null, "transform","translate("+x+")");

}
rect {
  transition: all 700ms ease-in-out;
}

text {
  transition: all 700ms ease-in-out;
}
svg {
	border: 1px solid purple;
}
<svg width="500" height="200">
  <defs>
    <mask id="mask1" x="0" y="0" width="500" height="200">
      <rect x="0" y="0" width="200" height="200" fill="#ffffff" stroke="none"/>
    </mask>
  </defs>
  <rect id="rect1" x="0" y="10" width="20" height="20" fill="blue" stroke="none" mask="url(#mask1)"/>
  <text id="text1" x="0" y="50" fill="red" stroke="none" mask="url(#mask1)">Hello</text>
  <g mask="url(#mask1)">
    <rect id="rect2" x="0" y="60" width="20" height="20" fill="blue" stroke="none"/>
    <text id="text2" x="0" y="100" fill="red" stroke="none">Hello</text>
  </g>
  <rect x="0" y="0" width="200" height="200" fill="none" stroke="lime" stroke-width="2"/>
</svg>
<br>
<button>animate</button>
<p>
The green outline shows the position of the mask rect
</p>
0 голосов
/ 12 октября 2018

Вместо этого вы можете использовать перевод:

document.querySelector("button").onclick = function() {
  var x = Math.random() * 250;
  document.querySelector("rect").setAttributeNS(null, "transform","translate("+x+")");
  document.querySelector("text").setAttributeNS(null, "transform","translate("+x+")");
}
rect {
  transition: all 700ms ease-in-out;
}

text {
  transition: all 700ms ease-in-out;
}
<svg width="500" height="100">
  <rect x="100" y="10" width="30" height="30" fill="blue" stroke="none"/>
  <text x="100" y="80" fill="red" stroke="none">Hello</text>
</svg>
<br>
<button>animate</button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...