[英]JS Proxying HTML5 canvas context
我希望代理畫布API,以便我可以測試抽象方法實際繪制到畫布,但是我遇到問題,在代理后我得到一個錯誤:
'strokeStyle' setter called on an object that does not implement interface CanvasRenderingContext2D
此代碼已簡化但引發相同的錯誤:
/** !NB: This snippet will probably only run in Firefox */ var canvas = document.createElement("canvas"); canvas.width = 100; canvas.height = 100; canvas.style.backgroundColor = '#FF0000'; var ctx = canvas.getContext("2d"); var calls = []; var handler = { get( target, property, receiver ) { if ( typeof ctx[property] === 'function' ){ return function( ...args ){ calls.push( { call: property, args: args } ) return ctx[property]( ...args ); }; } return ctx[property]; } }; try { document.body.appendChild(canvas); var proxy = new Proxy( ctx, handler ); proxy.scale( 1, 1 ); proxy.strokeStyle = '#000000'; canvas.getContext = function(){ return proxy; }; } catch( e ) { document.getElementById('message').innerHTML = 'Error: ' + e.message; }
<div id="message"></div>
有什么想法嗎?
您可以通過在處理程序上定義set
方法來修復此錯誤:
set(target, property, value, receiver) {
target[property] = value;
}
這個錯誤的原因可能看起來有點奇怪。 CanvasRenderingContext2D
實例沒有自己的strokeStyle
屬性。 相反, CanvasRenderingContext2DPrototype
(每個CanvasRenderingContext2D
實例的原型)都有一個訪問器屬性,其set
/ get
組件將設置並獲取實例的筆觸樣式值:
> ctx.hasOwnProperty("strokeStyle")
false
> Object.getOwnPropertyDescriptor(ctx.__proto__, "strokeStyle")
Object { get: strokeStyle(), set: strokeStyle(), enumerable: true, configurable: true }
(如果您有興趣了解有關此模式的更多信息,請查看我對JSON.parse的回答, 而不是在循環對象上出錯 。)
這里的問題是, this
提供給CanvasRenderingContext2DPrototype.strokeStyle
二傳手是proxy
對象,而不是實際的ctx
對象。 也就是說,當我們僅在代理上設置屬性時:
proxy.isAFake = true;
並在重新定義的setter中測試它:
Object.defineProperty(ctx.__proto__, "strokeStyle", {
set: function() {
console.log("strokeStyle setter called for proxy?", this.isAFake);
}
});
我們看到setter記錄了僅代理屬性: strokeStyle setter called for proxy? true
strokeStyle setter called for proxy? true
。
無論出於何種原因, CanvasRenderingContext2DPrototype.strokeStyle
上的setter只接受真正的CanvasRenderingContext2D
實例,而不是代理實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.