2013-06-22 54 views
1

我需要在每次調用函數drawImage()時在畫布2D上下文中執行一些代碼。如何在純JavaScript中重寫原生JS函數(canvas的drawImage())?

game.canvas = document.getElementById('canvas'); 
game.ctx = game.canvas.getContext("2d"); 

不幸的是,它並不像看起來那麼容易。

我試着這樣做:

game.ctx.drawImageOld = game.ctx.drawImage; 
game.ctx.drawImage = function(i,x,y,u,v){console.log("ok"); game.ctx.drawImageOld(i,x,y,u,v);} 
game.ctx.drawImage(myImage, 10, 10); 
// logs "ok" two times on FF 

CanvasRenderingContext2D.prototype.drawImageOld = CanvasRenderingContext2D.prototype.drawImage; 
CanvasRenderingContext2D.prototype.drawImage = function(i,x,y,u,v){console.log("ok"); this.drawImageOld(i,x,y,u,v);} 
game.ctx.drawImage(myImage, 10, 10); 
// logs "ok" two times 

但永遠不會執行本地的drawImage ...

我該怎麼辦呢?還有另一種「檢測」功能調用的方法嗎?

謝謝。

+0

感謝'this.drawImageOld'而不是'CanvasRenderingContext2D.prototype.drawImageOld' –

+0

謝謝,但它也記錄了兩次「ok」。 –

回答

3

當你調用

CanvasRenderingContext2D.prototype.drawImageOld(i,x,y,u,v); 

然後裏面drawImageOldthis將把CanvasRenderingContext2D.prototype,而不是實際的Context2D實例。這基本上是錯誤告訴你的。

您可以使用.call[MDN].apply[MDN]明確通過實例一起:

(function() { 
    var orig_drawImage = CanvasRenderingContext2D.prototype.drawImage; 

    CanvasRenderingContext2D.prototype.drawImage = function() { 
     console.log("ok"); 
     orig_drawImage.apply(this, arguments); 
    }; 
}()); 

然後雖這麼說,它不能保證,這將在所有的瀏覽器。主機對象,即ECMAScript規範未涉及的對象,並不總是必須遵守所有的規則。某些瀏覽器也可能將drawImage定義爲只讀。

+0

非常感謝!我今天學到了東西! –