1

raphael.js 的新手,我正在寻找关于如何做一些事情的解释,比如在轨道上围绕太阳移动行星。我一直试图创建一条路径并为围绕它的圆圈的运动设置动画。

感谢您提供正确方向的任何指示!

4

2 回答 2

7

我的朋友@Kevin Nielsen 是对的,你会想要“getPointAtLength”。这里有一个不错的小 Raphael 函数,它添加了一个 .animateAlong() 函数,尽管它需要一些修改才能处理圆形对象。我把它剥离成你的必需品。

假设您认识 1609 年后的天文学,您将需要椭圆轨道。(虽然实际上短半径和长半径的差异很小,这就是哥白尼有点偏离标准的原因。)但是你不能使用 .ellipse() 函数,因为你需要椭圆作为路径为了沿着它制作动画。请参阅椭圆弧的 SVG 规范,或者只是尝试一堆组合,直到看起来正确,就像我做的那样:

var paper = Raphael("canvas", 500, 500);

var center = {x: 200, y: 100 };
var a = 100;
var b = 80;

//see http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
var ellipse = "M" + (center.x - a) + "," + center.y + " a " + a + "," + b + " 0 1,1 0,0.1";

var orbit = paper.path(ellipse);

现在你想在椭圆的一个焦点上画地球,沿着路径画月亮。我们将从近地点开始。

var focus = Math.pow(a*a - b*b, 0.5);

var palebluedot = paper.circle(center.x - focus, center.y, 25)
    .attr({
        stroke: 0,
        fill: "blue"    
    });

var moon = paper.circle(center.x - a, center.y, 10)
.attr({
    stroke: 0,
    fill: "#CCC"
});

这是您修改后的“animateAlong”函数:

//Adapted from https://github.com/brianblakely/raphael-animate-along/blob/master/raphael-animate-along.js
Raphael.el.animateAlong = function(path, duration, easing, callback) {
    var element = this;
    element.path = path;
    element.pathLen = element.path.getTotalLength();    
    duration = (typeof duration === "undefined") ? 5000 : duration;
    easing = (typeof easing === "undefined") ? "linear" : duration;

    //create an "along" function to take a variable from zero to 1 and return coordinates. Note we're using cx and cy specifically for a circle    
paper.customAttributes.along = function(v) {
        var point = this.path.getPointAtLength(v * this.pathLen),
            attrs = {
                cx: point.x,
                cy: point.y 
            };
        this.rotateWith && (attrs.transform = 'r'+point.alpha);
        return attrs;
    };    

    element.attr({along: 0 }).animate({along: 1}, duration, easing, function() {
        callback && callback.call(element);
    });    
};

这是:

moon.animateAlong(orbit, 2000);

jsFiddle

于 2013-03-12T19:23:19.873 回答
1

@Chris Wilson 的答案是正确的。

我需要的一项细微修改是让动画无限重复。@boom 没有特别要求,但我可以想象这可能是轨道动画的常见要求,这是我对 Chris 版本的修改.animateAlong()

Raphael.el.animateAlong = function(path, duration, repetitions) {
    var element = this;
    element.path = path;
    element.pathLen = element.path.getTotalLength();    
    duration = (typeof duration === "undefined") ? 5000 : duration;
    repetitions = (typeof repetitions === "undefined") ? 1 : repetitions;

    paper.customAttributes.along = function(v) {
    var point = this.path.getPointAtLength(v * this.pathLen),
        attrs = { cx: point.x, cy: point.y };
    this.rotateWith && (attrs.transform = 'r'+point.alpha);
    return attrs;
    };    

    element.attr({along:0});
    var anim = Raphael.animation({along: 1}, duration);
    element.animate(anim.repeat(repetitions)); 
};

请注意,我已经删除了缓动和回调参数(因为我不需要它们)并添加了repetitions指定要执行的重复次数的参数。

一个示例调用(开始一个无限循环的轨道动画)是:

moon.animateAlong(orbit, 2000, Infinity);

于 2013-08-04T20:27:38.717 回答