我對畫布有點新鮮,如果這是一個微不足道的問題,那麼原諒。html5畫布 - 按路徑動畫對象
我想能夠跟隨一個路徑(定義爲貝塞爾路徑),但我不知道該怎麼做。
我已經看過拉斐爾了,但是我無法弄清楚隨着時間的推移如何跟隨路徑。
Cake JS在演示中看起來很有希望,但我真的在掙扎文檔,或者在這種情況下缺乏文檔。
有沒有人有這樣的工作例子?
我對畫布有點新鮮,如果這是一個微不足道的問題,那麼原諒。html5畫布 - 按路徑動畫對象
我想能夠跟隨一個路徑(定義爲貝塞爾路徑),但我不知道該怎麼做。
我已經看過拉斐爾了,但是我無法弄清楚隨着時間的推移如何跟隨路徑。
Cake JS在演示中看起來很有希望,但我真的在掙扎文檔,或者在這種情況下缺乏文檔。
有沒有人有這樣的工作例子?
使用this related question中的代碼on my website,但不是在回調中更改.style.left
等,而是使用新位置處的項目(可選擇旋轉)擦除並重新繪製畫布。請注意,這使用SVG內部很容易沿bézier曲線插入點,但是您可以使用它爲您提供的任意點(包括在畫布上繪圖)。
如果我的網站已關閉,這裏的圖書館的當前快照:
function CurveAnimator(from,to,c1,c2){
this.path = document.createElementNS('http://www.w3.org/2000/svg','path');
if (!c1) c1 = from;
if (!c2) c2 = to;
this.path.setAttribute('d','M'+from.join(',')+'C'+c1.join(',')+' '+c2.join(',')+' '+to.join(','));
this.updatePath();
CurveAnimator.lastCreated = this;
}
CurveAnimator.prototype.animate = function(duration,callback,delay){
var curveAnim = this;
// TODO: Use requestAnimationFrame if a delay isn't passed
if (!delay) delay = 1/40;
clearInterval(curveAnim.animTimer);
var startTime = new Date;
curveAnim.animTimer = setInterval(function(){
var now = new Date;
var elapsed = (now-startTime)/1000;
var percent = elapsed/duration;
if (percent>=1){
percent = 1;
clearInterval(curveAnim.animTimer);
}
var p1 = curveAnim.pointAt(percent-0.01),
p2 = curveAnim.pointAt(percent+0.01);
callback(curveAnim.pointAt(percent),Math.atan2(p2.y-p1.y,p2.x-p1.x)*180/Math.PI);
},delay*1000);
};
CurveAnimator.prototype.stop = function(){
clearInterval(this.animTimer);
};
CurveAnimator.prototype.pointAt = function(percent){
return this.path.getPointAtLength(this.len*percent);
};
CurveAnimator.prototype.updatePath = function(){
this.len = this.path.getTotalLength();
};
CurveAnimator.prototype.setStart = function(x,y){
var M = this.path.pathSegList.getItem(0);
M.x = x; M.y = y;
this.updatePath();
return this;
};
CurveAnimator.prototype.setEnd = function(x,y){
var C = this.path.pathSegList.getItem(1);
C.x = x; C.y = y;
this.updatePath();
return this;
};
CurveAnimator.prototype.setStartDirection = function(x,y){
var C = this.path.pathSegList.getItem(1);
C.x1 = x; C.y1 = y;
this.updatePath();
return this;
};
CurveAnimator.prototype.setEndDirection = function(x,y){
var C = this.path.pathSegList.getItem(1);
C.x2 = x; C.y2 = y;
this.updatePath();
return this;
};
...這是如何使用它:
var ctx = document.querySelector('canvas').getContext('2d');
ctx.fillStyle = 'red';
var curve = new CurveAnimator([50, 300], [350, 300], [445, 39], [1, 106]);
curve.animate(5, function(point, angle) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillRect(point.x-10, point.y-10, 20, 20);
});
我不會使用Canvas,除非你真的必須這樣做。 SVG在內置的路徑中有動畫.Canvas需要相當多的數學才能使其工作。
Here's one example of SVG animating along a path。
下面是一些關於它的討論,爲拉斐爾:SVG animation along path with Raphael
請注意,拉斐爾使用SVG和不 HTML5畫布。沿着在畫布貝塞爾路徑動畫
一種方法是連續平分貝塞爾曲線,recoring中點,直到你有很多的點(比如說,每曲線50分),你可以沿着動畫的對象的點的列表。搜索bisecting貝塞爾和相關的數學相似的查詢。
感謝您的輸入。大多數的SVG動畫的例子,我發現看...笨重 – Ben 2012-02-14 04:17:48
所以,這裏是詳細的版本:
t
是0和1之間的任何數字,代表時間;所述p0
,p1
,p2
,p3
對象是開始點時,第一控制點時,第二控制點分別是所述終點:
var at = 1 - t;
var green1x = p0.x * t + p1.x * at;
var green1y = p0.y * t + p1.y * at;
var green2x = p1.x * t + p2.x * at;
var green2y = p1.y * t + p2.y * at;
var green3x = p2.x * t + p3.x * at;
var green3y = p2.y * t + p3.y * at;
var blue1x = green1x * t + green2x * at;
var blue1y = green1y * t + green2y * at;
var blue2x = green2x * t + green3x * at;
var blue2y = green2y * t + green3y * at;
var finalx = blue1x * t + blue2x * at;
var finaly = blue1y * t + blue2y * at;
Here is a ball using <canvas> following a path in JSfiddle
個變量的名稱來自這個GIF至極是貝塞爾曲線的最佳闡釋:http://en.wikipedia.org/wiki/File:Bezier_3_big.gif
代碼的短版,功能準備複製/粘貼內:
var calcBezierPoint = function (t, p0, p1, p2, p3) {
var data = [p0, p1, p2, p3];
var at = 1 - t;
for (var i = 1; i < data.length; i++) {
for (var k = 0; k < data.length - i; k++) {
data[k] = {
x: data[k].x * at + data[k + 1].x * t,
y: data[k].y * at + data[k + 1].y * t
};
}
}
return data[0];
};
相關的東西:
感謝這個晚期的貢獻。但是沒有必要這麼傲慢。@ phrogz的答案非常棒,可以在任何路徑上工作。 – Ben 2013-02-15 06:05:20
離真棒很遠;它使用一個專有的庫,它有一個人的代碼太多,它使用的SVG速度較慢,在Android和其他設備上不受支持。 ---- 這也適用於任何路徑;只需更改p0,p1,p2和p3的值即可。如果您需要幫助獲取正確的數字,您可以使用「相關內容」中的第一個鏈接。 – 2013-02-15 08:22:29
想要在沒有畫布的情況下看到它嗎?這裏是:http://jsfiddle.net/aVwYL/1/ – 2013-02-15 08:31:56
hmmmm,有趣... – Ben 2012-02-14 04:17:58
這實際上適用於任何svg路徑...只需要將this.path.setAttribute更改爲具有給定路徑的init .. – Ben 2012-02-14 04:54:53
@Ben當然它。 :)你可能對[這是我的相關頁面]感興趣(http://phrogz.net/svg/convert_path_to_polygon.xhtml)。 – Phrogz 2012-02-14 04:56:10