【问题标题】:HTML canvas proxy getContext issueHTML画布代理getContext问题
【发布时间】:2020-10-19 15:20:39
【问题描述】:

在一个网站的 javascript 用户脚本中,该网站的画布 ID 为“canvas”,我使用以下代码使用 unsafeWindow 来制作该画布的代理:

const proxy = new Proxy(unsafeWindow.HTMLCanvasElement.prototype.getContext, {
    apply(target, thisArg, args) {
        const ctx = Reflect.apply(...arguments);

        const prototype = Object.getPrototypeOf(ctx);
        const descriptors = Object.getOwnPropertyDescriptors(prototype);

        Object.defineProperties(prototype, {
            arc: {
                value(x, y, radius, startAngle, endAngle) {
                        const { a, b, c, d, e, f } = ctx.getTransform();
                        const scale = 2;
                        ctx.setTransform(a * scale, b, c, d * scale, e, f);

                    return descriptors.arc.value.call(this, ...arguments);
                }
            },
        });

        return ctx;
    }
});
unsafeWindow.HTMLCanvasElement.prototype.getContext = proxy;

但每次在该脚本中我调用像const canvas = document.getElementById('canvas').getContext('2d'); 这样的画布,它调用代理,例如在这里,对于弧属性,每次调用document.getElementById('canvas').getContext('2d') 时都会应用一次比例尺,有人知道吗?如何在不调用代理的情况下调用document.getElementById('canvas').getContext('2d')

【问题讨论】:

  • 这是个有趣的东西...... TIL 代理是一个东西。在 Proxy 使用 getContext 方法作为其目标之前,您能否存储对画布 2d 上下文的引用?

标签: javascript html canvas proxy


【解决方案1】:

解决了, 使用它:

const proxy = new Proxy(unsafeWindow.OffscreenCanvas.prototype.getContext, {
    set: (target, key, value) => {
        return true;
    },
    get: (target, key) => {
        if (key !== "__isProxy") {
            return target[key];
        }

        return true;
    },
    apply(target, thisArg, args) {
        if (args[0] === 'noProxy') return Reflect.apply(target, thisArg, args.slice(1));
        const ctx = Reflect.apply(...arguments);

        const prototype = Object.getPrototypeOf(ctx);
        const descriptors = Object.getOwnPropertyDescriptors(prototype);

        Object.defineProperties(prototype, {
            arc: {
                value(x, y, radius, startAngle, endAngle) {
                        const { a, b, c, d, e, f } = ctx.getTransform();
                        const scale = 2;
                        ctx.setTransform(a * scale, b, c, d * scale, e, f);

                    return descriptors.arc.value.call(this, ...arguments);
                }
            },
        });

        return ctx;
    }
});
unsafeWindow.OffscreenCanvas.prototype.getContext = proxy;

并用它调用画布:

canvas = document.getElementById('canvas').getContext('noProxy', '2d');

【讨论】:

    猜你喜欢
    • 2016-06-22
    • 2011-10-11
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 2014-09-11
    • 2011-05-31
    相关资源
    最近更新 更多