我有下面的svg代码行:
<svg height="100%" width="100%">
<line id="skyline" x1="50%" y1="50%" x2="50%" y2="90%" style="stroke:rgb(0,0,0);stroke-width:10" />
</svg>尝试多次旋转直线似乎会将许多旋转(X)添加到transform属性,而不是每次都简单地覆盖该值:
var skyline = document.getElementById("skyline");
for (i = 0; i < 100; i++) {
var rotation = skyline.getAttribute("transform") + i;
skyline.setAttribute("transform", "rotate(" + rotation + ")");
}如何正确获取旋转属性,以及如何多次正确覆盖?
发布于 2016-07-14 21:35:55
在同步循环中更改相同的属性是没有意义的。如果你想要某种动画,你需要引入时间延迟。最直接的方法是使用setTimeout
var skyline = document.getElementById("skyline");
var angle = getOriginalAngle(),
finalAngle = angle + 100;
function rotate() {
skyline.setAttribute("transform", "rotate(" + (angle++) + "deg)");
(angle < finalAngle) && setTimeout(rotate, 12); // repeat every 12 ms
}
rotate(); // launch animation或者,如果您希望您的更改与浏览器呈现循环同步,则可以使用requestAnimationFrame
function rotate() {
skyline.setAttribute("transform", "rotate(" + (angle++) + "deg)");
(angle < finalAngle) && requestAnimationFrame(rotate); // +- 60 fps
}发布于 2016-07-14 21:35:14
假设您的线路还没有transform,您可以这样做:
var skyline = document.getElementById("skyline");
for (i = 0; i < 100; i++) {
skyline.setAttribute("transform", "rotate(" + i + ")");
}但是这并不能正常工作,因为您没有给浏览器一个呈现更新后的SVG的机会。而且,即使它确实更新了,它也会运行得太快。
因此,您需要使用间隔、超时或requestAnimationFrame()。
var i = 0;
function rotate() {
skyline.setAttribute("transform", "rotate(" + (i++) + ")");
if (i < 100)
setTimeout(rotate, 100);
}
setTimeout(rotate, 100);如果您的元素可能已经有一个转换,那么您将需要获取当前转换并对其进行操作。例如:
var i = 0;
function rotate() {
var matrixList = skyline.transform.baseVal;
if (matrixList.length === 0) {
skyline.setAttribute("transform", "rotate(" + (i++) + ")");
} else {
var firstTransform = matrixList.getItem(0);
firstTransform.setMatrix(firstTransform.matrix.rotate(1));
i++;
}
if (i < 100)
setTimeout(rotate, 100);
}
setTimeout(rotate, 100);
var skyline = document.getElementById("skyline");
var i = 0;
function rotate() {
var matrixList = skyline.transform.baseVal;
if (matrixList.length === 0) {
skyline.setAttribute("transform", "rotate(" + (i++) + ")");
} else {
var firstTransform = matrixList.getItem(0);
firstTransform.setMatrix(firstTransform.matrix.rotate(1));
i++;
}
if (i < 100)
setTimeout(rotate, 100);
}
setTimeout(rotate, 100);<svg height="100%" width="100%">
<line id="skyline" x1="50%" y1="50%" x2="50%" y2="90%" style="stroke:rgb(0,0,0);stroke-width:10" transform="rotate(-10)"/>
</svg>
发布于 2016-07-14 21:46:46
Greensock是CSS和JS的一个很好的扩展,它允许你根据相关元素的id或类名来操作SVG:
GreenSock
下面是一个例子:
TweenMax.staggerTo('.skyline', 2, {rotation: -90, repeat:-1, yoyo:true});<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.5/TweenMax.min.js"></script>
<svg height="100%" width="100%">
<line class="skyline" x1="50%" y1="50%" x2="50%" y2="90%" style="stroke:rgb(0,0,0);stroke-width:10" />
</svg>
最好的部分是它将在IE中运行,并且简单,易于实现,易于理解,并有很好的文档记录!它可以设置为在页面加载时自动运行,或者在触发事件(如悬停等)时自动运行。您可以选择它是否无限期运行或运行多少次,以及是否希望它具有yoyo效果(来回运行动画)。
https://stackoverflow.com/questions/38375573
复制相似问题