如何覆盖 fabric js 中的 canvas.add() 方法
how to override canvas.add() method in fabric js
我在一个图像编辑器中工作,我想在其中添加带有动画的图像到 canvas 中。
我尝试覆盖 canvas.add() 方法但无法播放动画。
我正在使用 fabric js 版本 1.7.22。
当我尝试谷歌搜索时。我找到了一种使用动画添加对象的解决方案,但在那个演示中,它们是自定义新方法 "fxadd()" 来添加对象。
参考文献link:
https://github.com/fabricjs/fabric.js/issues/77
但是我的代码太长了,根本不想替换函数名。
有什么方法可以覆盖现有的结构 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)
此处您将调用 function A
,将 fabric.Canvas.prototype.add
作为参数传递。这会创建一个闭包,将原始的 fabric.Canvas.prototype.add
保留在 function A
的范围内。然后,您将 function A
return 分配给 fabric.Canvas.prototype.add
。实际上,这转化为
fabric.Canvas.prototype.add = function B(argsB){ /*... */}
现在 function B
可以访问原始 fabric.Canvas.prototype.add
。
返回到您的代码片段,请注意您如何期望 object, callback
作为 function A
的参数,而 function B
中没有参数 - 这没有任何用处(见上文)。此外,当您调用 this.add()
时 - 这是您应该调用 original add()
而不是 new 的地方。否则,您将获得无限递归。
话虽如此,但正确的做法是:
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);
注意剩余参数 ...args
的用法,因为 add()
应该处理多个对象作为参数。我在第一个传递的对象上调用 animate()
,因此您可能想要更改它。
此外,不要忘记原始 add()
应该 return fabric.Canvas
的实例才能使链接工作,因此最后 return this
.
我在一个图像编辑器中工作,我想在其中添加带有动画的图像到 canvas 中。 我尝试覆盖 canvas.add() 方法但无法播放动画。
我正在使用 fabric js 版本 1.7.22。 当我尝试谷歌搜索时。我找到了一种使用动画添加对象的解决方案,但在那个演示中,它们是自定义新方法 "fxadd()" 来添加对象。
参考文献link: https://github.com/fabricjs/fabric.js/issues/77
但是我的代码太长了,根本不想替换函数名。 有什么方法可以覆盖现有的结构 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)
此处您将调用 function A
,将 fabric.Canvas.prototype.add
作为参数传递。这会创建一个闭包,将原始的 fabric.Canvas.prototype.add
保留在 function A
的范围内。然后,您将 function A
return 分配给 fabric.Canvas.prototype.add
。实际上,这转化为
fabric.Canvas.prototype.add = function B(argsB){ /*... */}
现在 function B
可以访问原始 fabric.Canvas.prototype.add
。
返回到您的代码片段,请注意您如何期望 object, callback
作为 function A
的参数,而 function B
中没有参数 - 这没有任何用处(见上文)。此外,当您调用 this.add()
时 - 这是您应该调用 original add()
而不是 new 的地方。否则,您将获得无限递归。
话虽如此,但正确的做法是:
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);
注意剩余参数 ...args
的用法,因为 add()
应该处理多个对象作为参数。我在第一个传递的对象上调用 animate()
,因此您可能想要更改它。
此外,不要忘记原始 add()
应该 return fabric.Canvas
的实例才能使链接工作,因此最后 return this
.