簡體   English   中英

JS Proxying HTML5畫布上下文

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM