2013-03-11 112 views
1

raphael.js的新手,我正在尋找關於如何在軌道上圍繞太陽移動行星等方面的解釋。我被困在試圖創建一個路徑併爲其周圍的圓圈運動設置動畫效果。與raphael.js軌道動畫?

感謝任何指向正確方向的指針!

+0

獲得正確的路徑將是挑戰性的部分。一旦你有了這些,可以很容易地使用getTotalLength和getPointAtLength函數(這兩個函數都是專門設計用於路徑元素的元素方法)來查找路徑中的特定點。看看這個:http://jsfiddle.net/gyeSf/17/ – 2013-03-12 00:42:08

回答

7

我的朋友@Kevin Nielsen是對的,你會想要「getPointAtLength」。有一個很好的Raphael函數here,它增加了一個.animateAlong()函數,雖然它需要一些修改來處理循環對象。我把它剝給你的必需品。

假設你認識1609後的天文學,you'll want elliptical orbits。 (雖然現實中短半徑和長半徑的差別很小,這就是爲什麼哥白尼有點離譜)。但是你不能使用.ellipse()函數,因爲你需要橢圓作爲一個路徑爲了動畫沿着它。請參閱SVG規範的elliptical arc,或只是嘗試了一堆的組合,直到它看起來正確的,像我一樣:

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

現在你想在橢圓的焦點之一繪製地球,月亮沿着路徑。我們將從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" 
}); 

下面是修改後的 「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

+1

不能相信這甚至沒有得到一個upvote!真棒解釋+小提琴,先生。 – 2013-03-31 14:33:11

+0

謝謝,先生! – 2013-03-31 21:21:27

+1

我不得不提到這個軌道(從小提琴)不是一個可變速度的(但它應該)。 – heltonbiker 2014-11-02 16:46:25

1

@克里斯·威爾遜的答案是正確的金錢。

我需要的一個細微修改是無限期重複動畫。 @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);