Skip to content

canvas.Image lacks onload #2264

Open
Open
@Pomax

Description

@Pomax

Issue or Feature

The Image implementation lacks an onload call (at least based on https://github.com/Automattic/node-canvas/blob/master/lib/image.js), making it impossible to use it "the normal way" where the onload is our signal that image data is available and now we can do something with that data.

(onload on the HTML side = incredibly bad, do not use. onload on the JS side: unfortunately still extremely necessary for Image, WebSocket, etc. etc. it never went away in JS land and we kept reinforcing it by introducing new object types that kept the onload and onerror pattern firmly alive right up to today =S)

Steps to Reproduce

const IN_BROWSER = !!globalThis.document;

let Image = globalThis.Image;
let createCanvas = (w, h) => {
  const cvs = globalThis.document.createElement(`canvas`);
  cvs.width = w;
  cvs.heigh = h;
 return cvs;
};

if (!IN_BROWSER) {
  const { createCanvas as create, Image as ImageClass } = await import(`canvas`);
  createCanvas = create;
  Image = ImageClass;
}

const img = new Image();
img.src = "./some/path.png";
img.onload = () => {
  // actually do things here, because we like idempotent code that just runs,
  // irrespective of whether it's in the browser or Node.js
  const myCanvas = createCanvas(...);
};

The above code won't actually do anything for node-canvas (but will run perfectly fine in the browser) because the shimmed Image has no code to trigger the onload "callback".

Suggested fix

Add an onload property with getter/setter:

Object.defineProperty(Image.prototype, 'onload', {
  get: function() { return this._onload },
  set: function(fn) {
    this._onload = fn;
    if (this.src) fn();
  }
);

And update setSource to something like

function setSource (img, src, origSrc) {
  SetSource.call(img, src)
  img._originalSource = origSrc
  img._onload?.()
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions