web-dev-qa-db-ja.com

html5キャンバス-パスをたどるオブジェクトのアニメーション

私はキャンバスに少し慣れていないので、些細な質問であれば許してください。

パス(ベジェパスとして定義)をたどるオブジェクトをアニメーション化できるようにしたいのですが、その方法がわかりません。

私はラファエルを見てきましたが、時間の経過とともに道をたどる方法を理解することができません。

Cake JSはデモでは有望に見えましたが、私は本当にドキュメントに苦労しているか、この場合はドキュメントが不足しています。

誰かがこれのいくつかの実用的な例を持っていますか?

18
Ben

コード 私のウェブサイト上 from この関連する質問 を使用しますが、コールバックで.style.leftなどを変更する代わりに、キャンバスを消去して再描画します。新しい場所のアイテム(およびオプションで回転)。

これは内部でSVGを使用してベジェ曲線に沿ってポイントを簡単に補間しますが、SVGが提供するポイントを必要なもの(キャンバスへの描画を含む)に使用できることに注意してください。

私のサイトがダウンしている場合に備えて、ライブラリの現在のスナップショットを次に示します。

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

動作中: http://jsfiddle.net/Z2YSt/

20
Phrogz

したがって、ここに詳細バージョンがあります。

tは、time;を表す0から1までの任意の数値です。 p0p1p2p3オブジェクトはstartポイント、1番目のコントロールポイント、2番目のコントロールポイント、エンドポイントそれぞれ:

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;

これが JSfiddle のパスをたどる<canvas>を使用したボールです。

変数の名前は、この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];
};



関連するもの:

8

本当に必要な場合を除いて、これにはCanvasを使用しません。 SVGには、パスに沿ったアニメーションが組み込まれています。Canvasを機能させるには、かなりの計算が必要です。

パスに沿ってアニメーション化するSVGの一例です

ラファエルについての議論は次のとおりです。 ラファエルのパスに沿ったSVGアニメーション

RaphaelはSVGとnotHTML5Canvasを使用していることに注意してください。


Canvasでベジェパスに沿ってアニメートする1​​つの方法は、ベジェカーブを連続的に二等分し、ポイントのリストに沿ってオブジェクトをアニメートできるポイントがたくさんなるまで(たとえば、カーブごとに50ポイント)中点を記録することです。二等分ベジエとそれに関連する数学の同様のクエリを検索します。

1
Simon Sarris