Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Canvas #241

Open
steel opened this issue Apr 7, 2021 · 22 comments
Open

Add support for Canvas #241

steel opened this issue Apr 7, 2021 · 22 comments
Labels
enhancement New feature or request

Comments

@steel
Copy link

steel commented Apr 7, 2021

e.g. document.createElement('canvas').getContext('2d')

@capricorn86
Copy link
Owner

Thanks for reporting @steel! 🙂

I will look into adding support for Canvas as soon as possible. However, being able to render graphics might be a bit challenging, but at least we can get support for the API.

@capricorn86 capricorn86 added the enhancement New feature or request label Jan 25, 2022
@taye
Copy link

taye commented Jan 29, 2022

@capricorn86 Just use https://www.npmjs.com/package/canvas :D

@Sparticuz
Copy link

@taye

@capricorn86 Just use npmjs.com/package/canvas :D

Are you saying that you can use that package to add in canvas support to happy-dom?

@capricorn86
Copy link
Owner

@Sparticuz I need to evaluate the package first. I am a bit worried that it is depended on OS system libraries to work, but on the other hand it seems quite popular 😅

@webChannelN
Copy link

FYI, adding canvas might mean impacting running tests in parallel for solutions using happy-dom for that:

Automattic/node-canvas#2019

For example:

vitest-dev/vitest#740

I just wanted to point it out, no real opinion otherwise (maybe some config can control these "if there is a peer I will depend on it" cases to give control over them, or maybe that is too much config... idk)

@huang-julien
Copy link

As @webChannelN said, node-canvas does not support workers environment

@markov00
Copy link

And also consider that node-canvas doesn't have prebuilt binaries for ARM64 Automattic/node-canvas#1662

@aurium
Copy link

aurium commented Apr 7, 2023

What about use jimp to implement a basic getContext('2d') support?

@Roosteridk
Copy link

https://github.com/google/skia/tree/main/modules/canvaskit runs completely on WASM

@Roosteridk
Copy link

Also we could at least add a canvas element as a stub for a future implementation

@jeevanpillay0000
Copy link

would like this implemented too. seems like node-canvas might have issues with things like lambda's. would recommend skia or napi-rs

@codepunkt
Copy link

Please don't use node-canvas for this 👍

@capricorn86
Copy link
Owner

I'm thinking about picking this up soon. I think that going with something like Skia seems like the best bet as performance is an important aspect here. I can imagine this being used in some applications for server side rendering and then we don't want any performance bottlenecks. However, it probably has to be an optional dependency or a plugin.

@weastaughscottlogic
Copy link

Hi @capricorn86 Any update on this and/or ETA on a resolution to this issue?

@capricorn86
Copy link
Owner

capricorn86 commented Feb 25, 2024

@weastaughscottlogic the update is that this is still high priority, but it is not a small task. It will probably be the next thing after going through the queue of pull requests and major bugs.

@KreutzVinicius
Copy link

Is there an workaround for this, while happy-dom still doesn't support the Canvas AP ?

@ImLunaHey
Copy link

if you're using vitest/jest you can use https://www.npmjs.com/package/vitest-canvas-mock or https://www.npmjs.com/package/jest-canvas-mock

@alex-bubblemaps
Copy link

Any solution for the bun's test runner ?

@capricorn86
Copy link
Owner

Hi! 👋
An update on this ticket:

I'm currently working on #1332, which will add basic support for HTMLCanvasElement, but will not add support for HTMLCanvasElement.getContext().

This ticket still has high priority and is one of the milestones for Happy DOM:
https://github.com/capricorn86/happy-dom/milestones

@twlite
Copy link

twlite commented Jul 4, 2024

Would it be possible to inject a custom canvas backend into the happy-dom library? I believe this could enhance the flexibility and extend the functionality of the library.

To illustrate what I mean, here's a simple pseudocode example in TypeScript:

async function resolveCanvas() {
  // Dynamically import the '@napi-rs/canvas' module
  const impl = await import('@napi-rs/canvas');

  return {
    // Function to create a new canvas with specified width and height
    createCanvas: (width, height) => impl.createCanvas(width, height),

    // Function to get the context of the canvas, e.g., '2d' or 'webgl'
    getContext: (canvas, ctx) => canvas.getContext(ctx),

    // Function to load and register a custom font
    loadFont: (fontData) => impl.GlobalFonts.register(fontData),

    // Additional methods for other canvas-related operations can be added here
    ...
  };
}

In this pseudocode:

  1. Dynamic Import: The @napi-rs/canvas module is dynamically imported, which allows for greater modularity and the possibility of substituting it with another implementation if needed.

  2. createCanvas: This function uses the impl.createCanvas method from the imported module to create a new canvas element with the specified dimensions.

  3. getContext: This function retrieves the rendering context for the canvas (e.g., '2d' or 'webgl').

  4. loadFont: This function registers a custom font using the impl.GlobalFonts.register method, allowing for the usage of custom fonts in the canvas rendering context.

I believe this approach could make happy-dom more versatile by allowing users to plug in different canvas implementations based on their specific requirements. It would also facilitate testing and potentially improve performance by leveraging optimized backends if needed.

@legend80s
Copy link

watch

@capricorn86
Copy link
Owner

Would it be possible to inject a custom canvas backend into the happy-dom library? I believe this could enhance the flexibility and extend the functionality of the library.

To illustrate what I mean, here's a simple pseudocode example in TypeScript:

async function resolveCanvas() {
  // Dynamically import the '@napi-rs/canvas' module
  const impl = await import('@napi-rs/canvas');

  return {
    // Function to create a new canvas with specified width and height
    createCanvas: (width, height) => impl.createCanvas(width, height),

    // Function to get the context of the canvas, e.g., '2d' or 'webgl'
    getContext: (canvas, ctx) => canvas.getContext(ctx),

    // Function to load and register a custom font
    loadFont: (fontData) => impl.GlobalFonts.register(fontData),

    // Additional methods for other canvas-related operations can be added here
    ...
  };
}

In this pseudocode:

  1. Dynamic Import: The @napi-rs/canvas module is dynamically imported, which allows for greater modularity and the possibility of substituting it with another implementation if needed.
  2. createCanvas: This function uses the impl.createCanvas method from the imported module to create a new canvas element with the specified dimensions.
  3. getContext: This function retrieves the rendering context for the canvas (e.g., '2d' or 'webgl').
  4. loadFont: This function registers a custom font using the impl.GlobalFonts.register method, allowing for the usage of custom fonts in the canvas rendering context.

I believe this approach could make happy-dom more versatile by allowing users to plug in different canvas implementations based on their specific requirements. It would also facilitate testing and potentially improve performance by leveraging optimized backends if needed.

@twlite I also had something like that in mind. Creating an API that allow to inject the Canvas logic. Then create a standard package for Canvas that is part of Happy DOM. The API would then allow to use any compatible module basically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests