Javascript 如何在fabric js中重写canvas.add()方法

Javascript 如何在fabric js中重写canvas.add()方法,javascript,animation,html5-canvas,fabricjs,add,Javascript,Animation,Html5 Canvas,Fabricjs,Add,我在一个图像编辑器中工作,我想用动画将图像添加到画布中。 我试图覆盖canvas.add()方法,但无法播放动画 我使用的是fabric js版本1.7.22。 当我尝试谷歌搜索时。我找到了一个通过动画添加对象的解决方案,但在那个演示中,他们使用自定义的新方法“fxadd()”来添加对象 以下是参考链接: 但我的代码太长,根本不想替换函数名。 有没有办法覆盖现有的fabric canvas.add()方法,请帮助我 fabric.Canvas.prototype.add = (function

我在一个图像编辑器中工作,我想用动画将图像添加到画布中。 我试图覆盖canvas.add()方法,但无法播放动画

我使用的是fabric js版本1.7.22。 当我尝试谷歌搜索时。我找到了一个通过动画添加对象的解决方案,但在那个演示中,他们使用自定义的新方法“fxadd()”来添加对象

以下是参考链接:

但我的代码太长,根本不想替换函数名。 有没有办法覆盖现有的fabric canvas.add()方法,请帮助我

fabric.Canvas.prototype.add = (function(object, callback) {
  return function() {
    console.log('add into canvas', this);
    this.add(object); // here call self method which result in infinit loop
    object.animate('top', '100', {
      onChange: this.renderAll.bind(this),
      duration: 1000,
      easing: fabric.util.ease.easeOutElastic,
      onComplete: function() {}
    });
  };
})(fabric.Canvas.prototype.add);

var canvas = new fabric.Canvas('canvas1')
var btn = document.getElementById('animate');

btn.addEventListener('click', function() {
  canvas.clear();
  setTimeout(function() {
    run();
  }, 800);
});
var run = function() {
  var rect = new fabric.Rect({
    left: 50,
    top: 10,
    fill: 'red',
    width: 100,
    height: 100,
  });

  canvas.add(rect)
}

看起来您正试图使用闭包覆盖原型方法,这通常是一种聪明的方法,只是在代码段中没有完全正确地完成。考虑一下你使用的构造的简化版本:

fabric.Canvas.prototype.add = (function A(argA) {
  return function B(argsB){
    //..
  }
})(fabric.Canvas.prototype.add)
在这里,您正在调用
函数A
,将
fabric.Canvas.prototype.add
作为参数传递。这将创建一个闭包,在
函数a
的作用域中保留原始的
fabric.Canvas.prototype.add
。然后,您将分配任何
函数A
返回到
fabric.Canvas.prototype.add
。实际上,这意味着

fabric.Canvas.prototype.add = function B(argsB){ /*... */}
只有现在
函数B
才可以访问原始的
fabric.Canvas.prototype.add

回到您的代码片段,请注意您是如何期望
对象、回调
作为
函数A
的参数,而
函数B
中没有参数的-这没有任何用处(参见上文)。此外,当您调用
this.add()
-这是您应该调用原始
add()
的地方,而不是新的。否则,将得到一个无限递归


话虽如此,以下是正确的方法:

fabric.Canvas.prototype.add = (function(originalFn) {
  return function(...args) {
    originalFn.call(this, ...args)
    args[0].animate('top', '100', {
        onChange: this.renderAll.bind(this),
        duration: 1000,
        easing: fabric.util.ease.easeOutElastic,
        onComplete: function () {
        }
    });
    return this
  };
})(fabric.Canvas.prototype.add);
注意rest参数
…args
的用法,因为
add()
应该处理多个对象作为参数。我正在对第一个传递的对象调用
animate()
,因此您可能需要更改它


另外,不要忘记原始的
add()
应该返回
fabric.Canvas
的实例以使链接正常工作,因此
在最后返回此

我试图覆盖Canvas.add()-你能准确地显示你尝试过的内容和没有成功的内容吗?这里是fiddle:请阅读fiddle中的注释。我已经写下了这个问题产生的原因。非常感谢您的帮助。它对我有用