首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JavaScript (而不是CSS)旋转SVG线

使用JavaScript (而不是CSS)旋转SVG线
EN

Stack Overflow用户
提问于 2016-07-14 21:27:56
回答 4查看 996关注 0票数 1

我有下面的svg代码行:

代码语言:javascript
复制
<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属性,而不是每次都简单地覆盖该值:

代码语言:javascript
复制
var skyline = document.getElementById("skyline");

for (i = 0; i < 100; i++) {
    var rotation = skyline.getAttribute("transform") + i;
    skyline.setAttribute("transform", "rotate(" + rotation + ")");
}

如何正确获取旋转属性,以及如何多次正确覆盖?

EN

回答 4

Stack Overflow用户

发布于 2016-07-14 21:35:55

在同步循环中更改相同的属性是没有意义的。如果你想要某种动画,你需要引入时间延迟。最直接的方法是使用setTimeout

代码语言:javascript
复制
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

代码语言:javascript
复制
function rotate() {
   skyline.setAttribute("transform", "rotate(" + (angle++) + "deg)");
   (angle < finalAngle) && requestAnimationFrame(rotate); // +- 60 fps
}
票数 2
EN

Stack Overflow用户

发布于 2016-07-14 21:35:14

假设您的线路还没有transform,您可以这样做:

代码语言:javascript
复制
var skyline = document.getElementById("skyline");

for (i = 0; i < 100; i++) {
    skyline.setAttribute("transform", "rotate(" + i + ")");
}

但是这并不能正常工作,因为您没有给浏览器一个呈现更新后的SVG的机会。而且,即使它确实更新了,它也会运行得太快。

因此,您需要使用间隔、超时或requestAnimationFrame()

代码语言:javascript
复制
var i = 0;

function rotate() {
  skyline.setAttribute("transform", "rotate(" + (i++) + ")");
  if (i < 100)
    setTimeout(rotate, 100);
}

setTimeout(rotate, 100);

如果您的元素可能已经有一个转换,那么您将需要获取当前转换并对其进行操作。例如:

代码语言:javascript
复制
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);

代码语言:javascript
复制
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);
代码语言:javascript
复制
<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>

票数 1
EN

Stack Overflow用户

发布于 2016-07-14 21:46:46

Greensock是CSS和JS的一个很好的扩展,它允许你根据相关元素的id或类名来操作SVG:

GreenSock

下面是一个例子:

代码语言:javascript
复制
TweenMax.staggerTo('.skyline', 2, {rotation: -90, repeat:-1, yoyo:true});
代码语言:javascript
复制
<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效果(来回运行动画)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38375573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档