Snap.svg animation stop() 不会停止动画

Snap.svg animation stop() doesn't stop animation

本文关键字:动画 svg animation stop Snap      更新时间:2023-09-26

我正在尝试沿着路径制作简单的动画,该路径在元素到达窗口边界时停止。下面是一些示例代码:

var s = Snap("#bouncy");
var ball = s.circle(100, 100, 10);
var mypath = getLinearPath({x: 300, y: 300}, {x: 300, y: -1000});
var windowBBox = s.getBBox();
function animateAlongPath(path, element, start, dur) {
    var len = Snap.path.getTotalLength(path);
    console.log(element);
    ball.current_anim = Snap.animate(start, len, function (value) {
        var movePoint = Snap.path.getPointAtLength(path, value);
        var ballBounds = element.node.getBoundingClientRect();
        if (Snap.path.isPointInsideBBox(windowBBox, movePoint.x, movePoint.y)) {
            console.log("moving to ", movePoint);
            var t = new Snap.Matrix();
            t.translate(movePoint.x, movePoint.y);
            element.transform(t);
        } else {
            console.log("stopping");
            this.stop();
            element.stop();
            ball.current_anim.stop();
        }
    }, dur);
};
function getLinearPath(start, end) {
    var p;
    p = s.path("M " + start.x + " " + start.y + " L " + end.x + " " + end.y);
    return p
};
animateAlongPath(mypath, ball, 0, 1000);

我只是想在球到达窗框顶部时停止动画。但是,当调用 stop() 时(在动画句柄或元素上),我继续收到回调,直到浏览器冻结。

如何取消动画并防止将来回调?

我阅读了Snap.svg的源代码,我发现anim.stop调用自己的回调函数。因此,在动画回调时调用 stop 方法会进行无限循环。

为了解决这个问题,你可以定义临时变量来阻止这样的无限循环。

var s = Snap("#bouncy");
var ball = s.circle(100, 100, 10);
var mypath = getLinearPath({x: 300, y: 300}, {x: 300, y: -1000});
var windowBBox = s.getBBox();
function animateAlongPath(path, element, start, dur) {
    var len = Snap.path.getTotalLength(path);
    console.log(element);
    ball.current_anim = Snap.animate(start, len, function (value) {
        var movePoint = Snap.path.getPointAtLength(path, value);
        var ballBounds = element.node.getBoundingClientRect();
        if (Snap.path.isPointInsideBBox(windowBBox, movePoint.x, movePoint.y)) {
            console.log("moving to ", movePoint);
            var t = new Snap.Matrix();
            t.translate(movePoint.x, movePoint.y);
            element.transform(t);
        } else {
            console.log("stopping");
            //this.stop();
            //element.stop();
            //NOTE: ball.current_anim.stop calls ball.current_anim
            var anim = ball.current_anim;
            delete ball.current_anim;
            if(anim){anim.stop();}
        }
    }, dur);
};
function getLinearPath(start, end) {
    var p;
    p = s.path("M " + start.x + " " + start.y + " L " + end.x + " " + end.y);
    return p
};
animateAlongPath(mypath, ball, 0, 1000);