【问题标题】:Using HTML5 canvas context as a prototype使用 HTML5 画布上下文作为原型
【发布时间】:2020-04-03 20:46:54
【问题描述】:

我正在尝试修改画布上下文对象的某些功能,而无需更改任何使用它的代码。 通过创建Proxy 对象的解决方案已在此处发布:JS Proxying HTML5 canvas context

我的问题是:通过使用ctx 作为原型,可以在不依赖Proxy 的情况下实现这种行为吗?

直接这样使用

let acx = Object.create(ctx, {})
acx.fillStyle = 'red'

导致与链接问题中提到的相同的错误消息

TypeError: 'set fillStyle' called on an object that
    does not implement interface CanvasRenderingContext2D.

在我测试过的所有 ctx 方法上。

在链接的问题中,这被解释为 CanvasRenderingContext2DPrototype 而不是 接受 假 ctx 对象。 accepting 到底是什么意思?有没有办法解决这个问题?

【问题讨论】:

    标签: javascript canvas html5-canvas prototype


    【解决方案1】:

    您可以存储画布上下文属性描述符,并重新定义所需的属性/方法。这是一种更复杂的方式,几乎可以完成代理的工作。

    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    var prototype = Object.getPrototypeOf(ctx);
    var descriptors = Object.getOwnPropertyDescriptors(prototype);
    
    Object.defineProperties(prototype, {
        fillStyle: {
            get() {
                console.log("Getting fillStyle");
                return descriptors.fillStyle.get.call(this);
            },
    
            set(value) {
                console.log("Setting fillStyle to", value);
                descriptors.fillStyle.set.call(this, value);
            }
        },
    
        fillRect: {
            value(x, y, w, h) {
                console.log("Drawing rectangle", x, y, w, h);
                return descriptors.fillRect.value.call(this, x, y, w, h);
            }
        }
    });
    
    var canvas2 = document.querySelector("canvas");
    var ctx2 = canvas2.getContext("2d");
    ctx2.fillStyle = "red";
    //>> Setting fillStyle to red
    ctx2.fillRect(10, 10, 100, 100);
    //>> Drawing rectangle 10 10 100 100
    <canvas id="canvas"></canvas>

    【讨论】:

      最近更新 更多