Использование контекста HTML5 canvas в качестве прототипа - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь изменить некоторые функциональные возможности объекта контекста холста без необходимости изменения какого-либо кода, который его использует. Решение для этого путем создания объекта Proxy было опубликовано здесь: JS Прокси HTML5 контекст холста .

Мой вопрос: можно ли добиться такого поведения, не полагаясь на Proxy при использовании ctx в качестве прототипа?

Непосредственное использование этого типа

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

приводит к тем же сообщениям об ошибках, что и упомянутые в связанном вопросе

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

на всех протестированных мной методах ctx.

В связанном вопросе это объясняется как CanvasRenderingContext2DPrototype, а не принятие поддельного объекта ctx. Что именно означает принятие здесь? Есть ли способ исправить это?

1 Ответ

0 голосов
/ 04 апреля 2020

Вы можете хранить дескрипторы свойств контекста холста и переопределять нужные свойства / методы. это более сложный способ сделать почти то же, что и прокси.

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>
...