第一次旋转后的 SnapSVG 旋转问题

SnapSVG rotation issue after first rotation

我在 this codepen 中创建了一个小演示。

单击四个按钮中的任何一个时,使用以下方法将对象旋转到正确位置...

function rotateTo(angle) {
      var ring = paper.select("#INNER_RING");
      var bbox = ring.getBBox();
      var cx = bbox.cx;
      var cy = bbox.cy;

      var trans = 'r' + angle + ' ' + cx + ' ' + cy; // + 's1,1,' + cx + ',' + cy;
      console.log(trans);

      ring.stop().animate({
          transform: trans
        },
        750,
        mina.linear,
        function() {
          settings.currentRotation = angle;
        });
    }

第一次轮换时,一切都很顺利。然而,随后的旋转不仅会旋转,而且会随着旋转的发生而缩放。该对象确实最终位于正确的最终位置,但不需要缩放。

作为第一个转换的一部分,会发生什么会导致后续转换这样做?

从先前的矩阵动画化矩阵通常会变得非常混乱,因为它们通常不会做我们认为它们会做的事情(我过去问过一个类似的问题 here 这可能有用,如果您想更深入地了解矩阵动画)。在第一个动画开始时,没有变换矩阵来制作动画,所以一切都非常简单。

但是,在第一个动画结束时,有一个应用于元素的转换矩阵留在那里,这会导致问题,因为下一个动画会尝试从最后一个矩阵开始动画。

不太清楚您在随后的按钮按下时实际想要做什么。是要旋转 'another' 90 度,还是再次从头开始旋转 90 度。

如果你只想重复动画,你可以将变换重置为 scratch,这可以简单地解决问题(但请注意,如果你在动画中按下按钮可能会出现问题)。

ring.attr('transform','')

jsbin

如果你想做更复杂的事情,并且需要从以前的状态开始动画,我会使用一种稍微不同的动画方法,而不是在元素上动画,而是使用 Snap.animate 并构建你的每次转换字符串。所以可能看起来更像这样...

var rotateFrom = settings.currentRotation;
var rotateTo = rotateFrom + parseInt(angle)

Snap.animate(rotateFrom, rotateTo, function( val ) {
    ring.transform( 'r' + val + ',' + cx + ',' + cy )
}, 750, mina.linear, function() {
    settings.currentRotation = rotateTo;
});

jsbin2

Snap.animate() 接受 2 个初始参数,即起始值和结束值,然后在它们之间进行插值,将其作为 'val' 传递给传入的函数。文档为此可以找到 here

这样一来,您就不必关心以前的变换(存储为矩阵)的动画效果,并且可以控制每个动画循环所发生情况的真实细节。

您可能只需要调整它并在每次调用 func 时(而不是在它完成时)存储旋转,这取决于您想要做什么 mid-animation 如果按钮在它被按下之前被按下完成。