使用 Snap SVG 的多阶段 svg 变换动画

Multistage of svg transform animation with Snap SVG

我正在构建一个小型 UI,它可以为用户提供下载或加载某些信息的进度。这是目前的代码

http://jsfiddle.net/pge1wukj/4/

    var s = Snap("svg");
    var movepath = s.select("#movePath").attr({
        "fill":"none"
    });
    var dapath = s.select("#dapath").attr({
        stroke: "#cdcdcd",
        "stroke-width": 5,
    });
    var dapoints = [242,334.5, 372,334.5, 372,390, 320.5,390.5 ,308.5,421.5 ,293.5,391.5 ,242,391]
    var circle = s.select("circle");
    var poly = s.select("polygon");

    $("a").click(function(){
        circle.animate({
            opacity: 0
        },100);
        poly.polyAnimate(dapoints,100,mina.linear,function(){
            moveAlongPath(poly,{x:308,y:421},s.halfArc(308,421,135,382,50,0),100);
        });
        dapath.animate({
        d:"M135,382.5c0,52.159,85,79.031,170.001,79.498 C 390.3,462.466,475.598,436.344,475,382.5",
    },100,function(){
        dapath.animate({d:"M135,382.5c0,0,85.999-0.467,171,0c85.299,0.468,169,0,169,0"
    },100,function(){
        dapath.animate({
        d:"M135,382.292c0,0,85.999-22.759,171-22.292c85.299,0.468,169,22.292,169,22.292"
        },100,function(){
            dapath.animate({
                d:"M136,382.415c0,0,90.999,13.118,176,13.585c85.299,0.468,164-13.585,164-13.585"
            },100,function(){
                dapath.animate({
                d:"M135,382.5c0,0,85.999-0.467,171,0c85.299,0.468,169,0,169,0"
                },500,mina.bounce,function(){
                var pathclone = dapath.clone().attr({
                    stroke: "blue",
                    strokeDashoffset: 500,
                    strokeDasharray: 500
                });
                var datext = s.text(100,330,"90").attr("style","text-align: center");
                var banner  = s.group(poly,datext);
                    moveAlongPath(banner,{x:136,y:382.415},movepath,3600);
                    var tick = 0; 
                    var interval = setInterval(function(){
                        tick += 1;
                        var red = Math.random()*255;
                        var blue = Math.random()*255;
                        var green = Math.random()*255;
                        var hex = Snap.rgb(red,green,blue);
                        var dadatext = $("text").text(tick+" %")
                        if(tick % 10 == 0){
                        dadatext.attr({"font-size":"30px","fill":hex});
                        };
                        if (tick >= 100){clearTimeout(interval)};
                        },36);
                    pathclone.animate({
                        "stroke-dashoffset":0,
                    },5300);
                    var paths = Snap.set().push(dapath,pathclone);
                     paths.animate({
                        d:"M135,382.5c0,0,30,17,42,17c10,0.208,298-17,298-17"
                    },300,function(){
                        paths.animate({
                            d:"M135,382.5c0,0,287,17.208,297,17c12,0,43-17,43-17"
                        },2900,function(){
                            paths.animate({d:"M135,382.5c0,0,287,17.208,297,17c12,0,43-17,43-17"},100,function(){
                                paths.animate({
                                    d:"M135,382.5c0,0,85.999-0.467,171,0c85.299,0.468,169,0,169,0"
                                },200,function(){
                                    $("a").off("click");
                                /* End of animation */
              /* Ready for next transformation*/
                banner.animate({
                transform: "rotate(180deg)"
                },200);
                                })
                            })
                        });
                    })

                });
        });
    })
    })
    });
    });`

动画结束时,横幅应在尖点处旋转 180 度。但是它没有像我预期的那样动画。有什么解决办法吗?转换动画很吓人,我不完全理解....

我认为您缺少的是您需要提供要包含的原始转换,否则它会假定您只是替换该转换。

所以这条线...

banner.animate({ transform: 'rotate(180)' },200);

这真正的意思是,我将覆盖所有当前的变换并制作一个新的 rotate(180) 动画。

您可能想要的是...保留所有现有变换,现在也旋转 (180)。

所以您可能想要更像这样的东西...不带参数的 transform() 将为我们提供现有的转换。这样我们就可以合并了。

变换 -> 现有变换然后应用附加变换

这看起来像下面这样。

banner.animate({ transform: banner.transform() + " s-1,1" },200);

我不太确定你想要的旋转效果(你的意思是上下颠倒还是回到前面?),但 's-1,1' 可能是你想要的。

jsfiddle 例子

编辑:jsfiddle 交替旋转。 请注意,为此,您需要考虑 'where' 多边形相对于组的偏移量,因为您移动了它(然后也移动了组)。

编辑:旋转中心点非常困难,因为我们有多边形点偏移(不是以 0 为中心)然后平移。他们所在的小组也已翻译,所以你有 3 件事情在进行。

为了尝试帮助理解获得实际点数,我重写了旋转动画。

banner.animate({ transform: banner.transform() + "r180," + banner.getBBox(1).cx + ',' + banner.getBBox(1).y2 },200);

我们得到了边界框,它为我们计算了中心。枢轴点是中间长度 cx,最低 y 点是 y2。 我怀疑有一种更简单的方法可以使整个过程工作以降低整个代码中的转换复杂性,但是这里要分解的问题太多了。

jsfiddle 与 getBBox