简体   繁体   English

使用raphael.js进行轨道动画制作?

[英]Orbit animation with raphael.js?

New to raphael.js, I'm looking for an explanation on how to do something like move planets around a sun in an orbit. 我是raphael.js的新手,我正在寻找有关如何做类似在行星绕太阳公转的事情的解释。 I'm stuck trying to create a path and animate the movement of the circle around it. 我一直在尝试创建路径并为围绕它的圆的运动设置动画。

Thanks for any pointers in the right direction! 感谢您指出正确的方向!

My friend @Kevin Nielsen is right, you'll want "getPointAtLength." 我的朋友@Kevin Nielsen是正确的,您需要“ getPointAtLength”。 There's a nice little Raphael function here that adds an .animateAlong() function, though it needs a little modification to work on circular objects. 这里有一个不错的Raphael小函数它添加了一个.animateAlong()函数,尽管它需要进行一些修改才能在圆形对象上工作。 I stripped it to the necessities for you. 我将其剥离为您的必需品。

Assuming you recognize post-1609 astronomy, you'll want elliptical orbits . 假设您认识到1609年以后的天文学,就需要椭圆轨道 (Though the difference in the short and long radii are quite small in reality, which is why Copernicus was a bit off the mark.) But you can't use the .ellipse() function, since you need the ellipse as a path in order to animate along it. (尽管实际上短半径和长半径的差异很小,这就是为什么哥白尼有点不合时宜的原因。)但是您不能使用.ellipse()函数,因为您需要使用椭圆作为路径为了沿它动画。 See the SVG specifications for the elliptical arc , or just try a bunch of combinations until it looks right, like I did: 请参阅椭圆弧的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);

Now you want to draw the earth at one of the foci of the ellipse, and the moon along the path. 现在,您要在椭圆的一个焦点处绘制地球,并沿路径绘制月亮。 We'll start it at the perigee . 我们将从近地点开始。

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"
});

And here's your modified "animateAlong" function: 这是修改后的“ 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);
    });    
};

and here it is: 这是:

moon.animateAlong(orbit, 2000);

jsFiddle jsFiddle

@Chris Wilson's answer is right on the money. @克里斯·威尔逊的答案是对的钱。

One slight modification I needed was to have the animation repeat indefinitely. 我需要做的一点修改就是使动画无限期地重复。 @boom doesn't ask for it specifically, but as I can imagine this could be a common requirement for orbit animations, here's my modification to Chris's version of .animateAlong() : @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)); 
};

Note that I've dropped the easing and callback parameters (as I didn't need them) and added the repetitions parameter, which specifies the number of repetitions to perform. 请注意,我已经删除了easing和callback参数(因为我不需要它们),并添加了repetitions参数,该参数指定要执行的重复次数。

An example call (starting an endlessly looping orbit animation) is: 一个示例调用(开始不断循环播放轨道动画)是:

moon.animateAlong(orbit, 2000, Infinity);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM