LoginSignup
2
2

More than 5 years have passed since last update.

RaphaelJS の animate() を jQuery Deferred と一緒に使う

Last updated at Posted at 2012-07-26

jQuery の animate() は Deferred オブジェクトを返すので、jQuery Deferred を使って対象の違うアニメーションを順番に実行 のように pipe() を使って順番に実行したり、when() で複数のアニメーションが終わるまで待ったり、柔軟なフロー制御ができます。一方、RaphaelJS の animate()Element/Set を返すので、そのままだと同様に扱うことができません。

そこで RaphaelJS の Element/Set に、jQuery の Deferred オブジェクトを返す animate() 的なものを追加してみました。Element/Setprototype は、それぞれ Raphael.elRaphael.st から参照できます。

Raphael.el.animateWithDeferred = Raphael.st.animateWithDeferred = function(params, ms, easing, callback) {
  var dfd = $.Deferred();
  this.animate(params, ms, easing, function() {
    if (typeof callback === 'function') {
          callback.apply(this, arguments);
    }
    dfd.resolve();
  });
  return dfd;
};

単純に callback をラップして Deferred#resolve() を呼ぶ実装です。これですと、もともとの animate() と違い、Animation オブジェクトを引数にとることができません。Animation オブジェクトにも対応したい場合は、以下のような感じにすると良いでしょう。

Raphael.el.animateWithDeferred = Raphael.st.animateWithDeferred = function(params, ms, easing, callback) {
  var dfd = $.Deferred(),
      isAnim = typeof params.anim === 'object',
      originalCallback = isAnim ? params.anim[100].callback : callback,
      callbackWithDeferred = function() {
        if (typeof originalCallback === 'function') {
          originalCallback.apply(this, arguments);
        }
        dfd.resolve();
      };
  if (isAnim) {
    params.anim[100].callback = callbackWithDeferred;
    this.animate(params);
  } else {
    this.animate(params, ms, easing, callbackWithDeferred);
  }
  return dfd;
};

ちなみに Animation オブジェクトを Set#animate() に渡すと、全ての子要素でアニメーションが終わるたびに callback が呼ばれてしまうのでので注意が必要です。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2