繁体   English   中英

使用CSS过渡为SVG元素的位置设置动画

[英]Using CSS transitions to animate the position of SVG elements

我想使用CSS过渡为SVG元素的位置设置动画。

但是-看起来这对某些SVG元素(例如rect)有效,但不适用于其他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的库)。

您可以改用翻译:

 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> 

正如Temani所说,正确的解决方案是使用transform

但是,在我的实际应用中-SVG元素在遮罩下移动,并且该转换似乎会引起意外的副作用。

这是因为对元素的变换也适用于应用于该元素的其他属性。 如口罩。 解决方法是将遮罩移至父组,以使其不受变换的影响

<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> 

您也可以通过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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM